Learn how HTTP caching works, and which headers are involved in determining whether a response from the API is cacheable.
- [Instructor] Caching is an important piece of any restful API. If resources and API responses are designed to be cached, clients won't need to make requests to the server again for the same resource while the cache is fresh. This reduces the load on your server and can increase both the response time of the API and the perceived response time in clients with cached responses. Caching involves both the client and the server. On the server side, your application can let clients know that responses are cachable in a few ways. The first is by returning the cache control header with a response.
The cache control header can specify the number of seconds a cached copy should be considered fresh or it can be used to disable caching entirely, by setting the no cache and no store directives. The expires header can also be used to let the client know how long to cache a request. If the date of the response is less than the time stamped in the header, the response is still fresh and it can be returned from the cache. If a response includes both cache control and expires, cache control takes priority in determining whether cached data is fresh. The amount of time to keep the data fresh in the cache is a trade off between reducing requests to the server and keeping the resource up to date.
For data that change frequently, you'll need to specify a short freshness window. On the other hand, static or nearly static data can have long freshness windows. Clients decide how to handle cache data depending on whether the cache is still fresh or it's become stale. When a client makes a request that could be fulfilled by cached data, it checks whether that data is still fresh in the cache or if it's gone stale. If it's fresh, the client can return the data straight from the cache and avoid making any network requests to the server. If it's stale, the data in the cache might still be valid or it might be out of date.
The client will need to check with the server to see if the cached copy is still valid. Validation headers are included on the outgoing request, which let the server know which version of the resource the client has in the cache. If the server determines that the resource still hasn't changed, it can send back the 304 not modified status and updated cache headers with new freshness information. The 304 not modified response doesn't include a response body because there's no need to re-transmit the whole resource if the cached copy is still good. This way, even though the client did need to make a network request to validate the cache with the server, the request is light and doesn't require much network bandwidth.
One way the client can validate a cached resource with the server is by using the last modified header. On the initial response, the server includes a time stamp that indicates the last time the resource was modified. When the client needs to validate a cached but stale version, it will attach the if modified since header to the validation request it sends to the server. If the resource has still not been modified, the server will respond with 304 not modified and updated freshness information. If the resource has been modified, the server would respond with a normal 200 okay response.
Another way of validating cached resources against the server is with the ETag header. On the original response, the server includes the ETag header which is a fingerprint or hash that uniquely identifies this version of a resource. If the resource changes on the server, a new ETag is calculated. When the client needs to validate a cached but stale version, it will attach the if none match header to the validation request it sends to the server. If the resource hasn't changed, the server will respond with 304 not modified and updated freshness information. If the resource has changed and the ETag no longer matches, the server will send a normal 200 okay response that includes the updated ETag fingerprint.
ETag validation is stronger and more accurate than validation with last modified because last modified is only accurate down to a second of resolution, whereas the ETag fingerprint will change anytime a resource is modified. Because of this, the ETag header will take priority over the last modified header if both are used. To recap, in order to support caching, the application should return the cache control or expires headers on resources that can be cached. The application should also return the last modified header for resources that support a modification time stamp or an ETag for resources that can be compared using a hash or fingerprint.
When the client attaches the if modified since or if none match headers, the application should compare the last modified date or the ETag fingerprint and return 304 not modified if the resource has still not changed. Now that we've taken a look at how caching works between the client and the server, let's add it to the Landon Hotel API.
- REST vs. RPC
- Using HTTP methods (aka verbs)
- Returning JSON
- Creating a new API project
- Building a root controller
- Routing to controllers with templates
- Requiring HTTPS for security
- Creating resources and data models
- Returning data and resources from a controller
- Representing links (HREFs)
- Representing collections
- Sorting and searching collections
- Creating forms
- Caching and compression
- Authentication and authorization for RESTful APIs