3

I have been given a project recently where REST API have been implemented in the most basic way possible i.e. request comes to app, app hits controller, queries db, returns response.

So this mechanism, as its quite obvious, has started to create issues in terms of response times as data has grown a lot. Plus this approach also hogs the infrastructure a lot as well through its processing.

Now, I'm familiar with caching mechanisms for APIs and non API things, but what are the recommended ways to do it in case of APIs? Also, what do we need to add in terms of infrastructure and code modules to handle such sort of a thing?

Some test cases for different approaches would be really nice by any of the well-versed folks.

2 Answers 2

4

For a REST service, you usually want to use the available caching mechanisms of the web and the HTTP protocol. That means using caching directives or entity tags in the responses.

In this context, what you want to do is to completely eliminate some requests to certain resources or limit the work that the server needs to do once a request is received.

You need to analyze your application and:

  • decide for how much time resources are safe to cache on the client side. If something can safely be cached for a couple of days then you says so in the response. If a client uses the same resource again, it won't make a request to the server since it already has it cached.
  • If some resources can't safely be cached on the client side then you can cache on the server. This is where ETags come in. Client asks, "Hey server, I have this version. Is it still good?". Server then says it's good or else gives you the latest data. The new data has now another ETag and you can repeat the process.

You should do a search online for something like "REST API caching strategies" and see if something else might be more suitable for your case.

Now, of course, caching doesn't happen on it's own. You need to implement it. That means:

  • on the server side you need to add caching directives and entity tags, and implement this mechanism together with an actual cache that sits in front of your DB (frameworks usually have support for things like this up to some point - so they might get you part of the road there).
  • You need to make sure caching doesn't interfere with the consistency of your service's data;
  • clients need to play nice. If you put all this caching in place and clients decide to completely ignore it you pretty much worked for nothing. This is usually fixed by "forcing" the client to play nice and rejecting any requests that don't include the necessary headers for you to get a "cache hit". This might be harder to do if you already have clients that don't do caching and you need to make sure they don't brake.
0
1

Typically, this would be handled in a layer between the Controller and the DB (commonly, a layer implementing the Repository pattern). Within that Repository layer, you'd have code that handles the caching operations.

A naive implementation might just keep a list of previous requests and what the response was; if a new request is a match to something that was requested earlier, you pass back the same response (without hitting the DB to get it).

Then, you'd start improving that implementation - maybe by tracking when a cached response was last gotten from the DB, and deciding to grab it anew if the last time is older than some length of time.

You might also split out other cache invalidation strategies, and use different ones for different entities (some entities might need to never be cached, others might be cache-able based on number of times they were requested rather than time, and still others might need to have their cache invalidated by any time a write event occurs for an entity matching that ID... or possibly any write event for an entity of that type).

The basic thing here is that you want to split the logic out from the Controller, and ideally keep it separate from the code that actually queries the database.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.