I’m pretty glad I didn’t write any tests for my client architecture so far. Somehow I had the feeling that most of the code was going to be deleted. And guess what the feeling was right. Last week I replaced the complete middleware stack handling I described in the previous post with the Faraday gem and its friends.
Faraday is an HTTP client lib that provides a common interface over many adapters (such as Net::HTTP) and embraces the concept of Rack middleware when processing the request/response cycle.
Here’s how it works: If you supply a block to
Faraday.new you can use it to configure the stack.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
Faraday works pretty much like Rack::Builder. You compose the request/response pipeline out of middlewares via the
use method. They’re composed from top to botton.
response are just syntactic sugar for the configuration.
builder.request :json is nothing more than
builder.use Faraday::Request::Json, though it probably looks cooler the first way. Here’s the full commit that introduced
Faraday into the client.
The client is functional with this, but I lost all the caching capabilities. As I found out I couldn’t use
Rack::Cache as a middleware. The API’s look similar, but the
env hash which gets passed from middleware to middleware isn’t. But in the end this wasn’t a big problem. The faraday-http-cache gem does exactly what I need. And here comes the beauty of the middleware based model: All that needs to be done on the client side is to add a new middleware and you’re done!
I cheated a bit though. When I re-ran the client against the server, it didn’t cache. After a bit looking into the code of the
faraday-http-cache gem I realized that I had to include
public in the
Cache-Control directive returned with my responses in order to make it integrate well with the gem.
1 2 3
After changing that everything worked as expected. I’m a bit undecided regarding the
Cache-Control: public. For all I know this indicates that the response can be cached in shared public caches, which is probably something you often don’t want for your client.
private on the other hand indicates that content can be cached in the non-shared private cache of the client, which is in my opinion more appropriate for our scenario and a valid caching scenario. I guess it’s a bug in the
The full commit that introduced caching back into the client can be found here. I also removed the
Request base class in that commit, because it became unnecessary after the refactoring.
This is probably the end of the heavy client focus for a while. I think I’ve got a pretty good understanding now, how I would start with writing a client for a web API. Sure we haven’t talked about Hypermedia much so far, but we’ll catch up to that.
Next to the table on which I’m writing this post a sheet of paper is waiting to be used for a post. It’s from last October, specifically from the Dev Open Space 2012 in Leipzig. Sergey Shishkin and I used it to prepare a talk about Hypermedia. I won’t surprise you when I reveal that it shows a Hypermedia graph. This is where we continue next time.