Upgrade to Pro — share decks privately, control downloads, hide ads and more …

RESTful APIs - Versioning and Caching

Hendrik Saly
September 13, 2016

RESTful APIs - Versioning and Caching

Introduction in RESTful APIs with focus on versioning and caching

Hendrik Saly

September 13, 2016
Tweet

More Decks by Hendrik Saly

Other Decks in Programming

Transcript

  1. REST Maturity Model Level Meaning HTTP methods used 1 XML-RPC/SOAP

    with only one endpoint URI POST 2 Different endpoints and resources POST 3 Different endpoints and resources GET, POST, PUT, DELETE, … 4 Different endpoints and resources, HATEOAS GET, POST, PUT, DELETE, … (Typically level 3 is implemented)
  2. HATEOAS Hypermedia as the Engine of Application State Response contains

    hyperlinks to other resources Kind of finite state machine Not widely used { "name": "Foo", "links": [ { "rel": "self", "href": "http://localhost:8080/customer/1" } ], "details": "/details/1" }
  3. Meaning of HTTP methods Method Meaning Safe Idempotent Cacheable Has

    Body GET Read Y Y Y Response only HEAD Same as GET without body Y Y Y N POST Create N N Y Request/Response PUT Upsert N Y N Request/Response DELETE Delete N Y N Response only OPTIONS returns the HTTP methods that the server supports Y Y N Response only PATCH, TRACE, CONNECT, etc. are out of scope here
  4. Meaning of HTTP methods (2) URI type GET PUT POST

    DELETE Collection List of elements or URIs Replace entire collection create new collection delete complete collection Element Return element Replace or create element - delete element
  5. API versioning Why this might be necessary? API evolves over

    time Adding new resources or response parts is not critical but Renaming and/or deletion is Two possibilities to solve this Encode version of the API in the URI Encode version of the API in a header Depends especially on the type of client (Browser or other)
  6. URI versioning Pros Simple and clearly visible by looking on

    the URI Cons Its difficult to use separate parts of the API in different versions simultaneously Same resources have different URIs (REST constraint violation) Problem if client stores/bookmarks URIs cause also the version is stored along with the URI Can be used together with a Link header to relocate to newest API version /api/v1/customers/3
  7. Header versioning (Content negotiation) Pros Its easy to use separate

    parts of the API in different versions simultaneously Same resources have same URIs No problems with stored/bookmarked URIs Accept Header supports more than one version Accept: application/vnd.myapp-v1+json
  8. Header versioning (Content negotiation) (2) Cons Header is hidden You

    need own (self defined) mime types (thats no a real problem so far) To make HTTP caching work a Vary: Accept header is needed to make the Accept header part of the cache key Not widely spread (most devs are unfamiliar with that approach)
  9. API versioning - best practice Keep it simple for the

    developers and implement URI versioning Provide a non versioned URI alias which point to the most recent version For more complicated situations use Link header
  10. API caching Make sure all servers, proxies, web caches and

    clients support HTTP 1.1 Purpose is to decrease utilization of network bandwith/latency and discharge load on backend systems/HTTP server and therefore gain more performance (handle more load, increase responsiveness) Only GET and HEAD is cacheable If you not have such problems (and you don’t expect them in the future) do not use caching because there are several downsides
  11. API caching (1) Downsides Stale responses Invalidation Can get very

    complex Depending on a cache makes the cache mandatory
  12. API caching (2) There are three possibilities for caching: Let

    the browser do it Let the client do it (for example AngularJS caching) Cache costly backend operation on the server side (Not really API caching)
  13. API caching (3) Client side caching can reduce utilization of

    network bandwith and load on backend systems Clients are responsible, needs probably programming If client is a browser it depends on the implementation of the browser (IE and Safari might show bugs) It also depends on the infrastructure between the client and the originating server (proxies, webcaches, … ) For browser caches or HTPP 1.1 compliant client it work May i cache? If cached is it fresh? If stale is it valid on the server?
  14. States of Resource Representation Up-to-date (same as origin server) Fresh

    (as long as its not expired on client or proxy) Stale (expired)
  15. HTTP Cache-Control header An easy and simple method is to

    use the HTTP 1.1 Cache-Control header to indicate when a resource response is outdated. Until this point in time the browser will not connect to the rest endpoint but will server the response from its cache. What May be Stored by Caches (request/response) no-store no caching at all What is Cacheable (response only) public by any cache, no revalidation if fresh private by any non shared cache, no revalidation if fresh no-cache by any cache, enforce revalidation even if fresh (request/response)
  16. HTTP Cache-Control header (1) Expiration mechanism (request/response) max-age client is

    willing to accept a response whose age is no greater than the specified time Cache Revalidation and Reload Controls (response only) must-revalidate do an end-to-end revalidation every time proxy-revalidate sames as must-revalidate but not for private caches
  17. HTTP Cache-Control header (2) But thats really only suitable for

    static resources like CSS, Javascript, Images, etc. and not recommended for representations of business domain objects. Therefore do not use it for API caching.
  18. HTTP ETag header (Content-based) Another method is to use the

    ETag header to maintain a kind of hashcode for the content. Every time the content changes on the server side the value of the ETag does change. sent by origin server or the user agent Sometimes ETag is hard to maintain, especially in a distributed backend environment HTTP/1.1 200 OK ETag: "hgt5398j" GET /customer/1 HTTP/1.1 IF-None-Match: "hgt5398j" HTTP/1.1 304 Not Modified ETag: "hgt5398j"
  19. Server side application level caching Server side caching can reduce

    load on backend systems by caching data in memory Guava cache (which ships with Dropwizard) for costly database queries Simple Maps/Lists Needs enough memory to be available Invalidation is perfectly under control
  20. Client side application level caching Client side caching with Independent

    from the remote server or proxy Storage is Javascript heap memory AngularJS Alternatively angular-cache
  21. Combining header versioning and caching If the response depends on

    an Accept header too then we need to set the HTTP Vary Header (which is broken in IE and Safari) Normally content in the browser cache is matched agains its URI and HTTP Method. With the Vary Header additional constraints, like the Accept or Authorization header, can be included in the cache key. Vary: Accept
  22. Pitfalls Browser caches may not work for self-signed SSL certificates

    If a resource needs authentication this have to be included in the Vary header and Cache-control: private must be set to prevent shared caching of a security token Vary header is broken for some browsers and some types
  23. Recommended caching strategy for REST Best is do no caching

    at all If you must cache because of backend utilization Consider server side application level caching Consider HTTP content based caching with ETag validation Cache-Control: no-cache, max-age=0 for client Cache-Control: public, max-age=0, must-revalidate + ETag for server If you must cache because of network utilization Consider client side application level caching That is because of Browsers and intermediate infrastructure (like proxies are) are subject to change, sometimes buggy and sometimes
  24. Thank you! Follow me on Twitter: This work is licensed

    under a [email protected] @hendrikdev22 Creative Commons Attribution 4.0 International License