3 ms·
Know how to design a RESTful interface correctly, and you don’t need “API versioning”. Certainly not URL-based versioning, which is as anti-REST as it gets. Th
by hhas01 7y ago
Know how to design a RESTful interface correctly, and you don’t need “API versioning”. Certainly not URL-based versioning, which is as anti-REST as it gets.
The correct way to manage non-backwards-compatible changes in a RESTful system is to define a new content type for the resource representation that has changed.
For example, here is a JSON-encoded representation of a Person resource:
{"name": "Bob Jones", "age": 42}
To describe this particular data structure + encoding, we give it its own content type:
"application/org.example.person+json"
and provide public documentation for this representation type.
To retrieve a description of a given person in this exact format, a client sends a GET request with an "Accept: application/org.example.person+json" header.†
Let’s say after a while you decide to replace the "name" field with separate "firstName" and "lastName" fields:
{"firstName": "Bob", "lastName": "Jones", "age": 42}
This new representation clearly isn’t backwards-compatible, so give it a new content type that reflects this:
"application/org.example.person.v2+json"
and provide public documentation for this new representation type, alongside the documentation for the older format.
A newly written/updated client that requires this improved information sends a GET request with an "Accept: application/org.example.person.v2+json" header.
Existing clients that still use the old format continue to send GET requests with an "Accept: application/org.example.person+json" header.
Where there are many such servers all around the world, it is likely that some will be older than others. A client that much prefers the new, more detailed, representation but is prepared to work with the old-style representation if that’s all it can get will send an Accept header containing both content types weighted by preference:
"Accept: application/org.example.person.v2+json;q=1.0,
application/org.example.person+json;q=0.3"
No sequentially version-mangled URLs. No Grand New Major API Release Announcements. No “we have ended support for the v1 API so now you must switch to the v2”. Just flexible, reliable interactions between any number of clients and servers, where each client and each server is free to evolve naturally and non-disruptively over time.
TL;DR: Everything you think you know about RESTful HTTP is completely and utterly WRONG. Same goes for everyone you learnt it from, and so on. #FractallyWrong
--
† A client that doesn’t care what it receives as long as it’s JSON encoded can, of course, send an Accept header containing the basic "application/json" and if the server is happy to serve that particular idiot^Wtype then that’s what it gets back. A server is also free to represent the same resource in any number of encodings, e.g. "application/org.example.person+xml" (for All your Enterprisey™ clients), "text/html" (your Auntie Ena in her Internet Explorer 6 will always ask for this), and so on.
- philwelch 7y ago> The correct way to manage non-backwards-compatible changes in a RESTful system is to define a new content type for the resource representation that has changed. And this is the fundamental problem with REST and why nobody actually uses "True REST". People don't merely use API's to exchange representations of resources. They use API's to order pizzas, hail Ubers, subscribe to YouTube channels, update parameters for Netflix recommendations, and do lots of other things that have real-world side-effects. You can of course shoehorn all of this into a REST abstraction, just as you can represent all computation as a Kingdom of Nouns (https://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html https://steve-yegge.blogspot.com/2006/03/execution-in-kingdo...), but is there any actual benefit in doing so? The more general, time-tested, and useful abstraction has always been RPC, which is why virtually every real-world "REST API" is just RPC over HTTP, except without the heavyweight mumbo-jumbo of SOAP and with some attention paid to the proper use of HTTP verbs. This is not a bad thing.
- hhas01 7y ago“They use API's to order pizzas, hail Ubers, subscribe to YouTube channels, update parameters for Netflix recommendations, and do lots of other things that have real-world side-effects.” That’s three POSTs and a PUT, with the appropriate content types; absolute bread-and-butter RESTful interactions. At least try to pick something behaviorally awkward for HTTP, like COPY or SEARCH. If you can’t see how to express changes to a remote state machine in RESTful terms, with cascading sequences of automatic behaviors and subsequent state updated triggered off the back of that, I seriously doubt your competence to express them any more reliably using plain dumb RPC without a whole host of $UNDEFINED_BEHAVIORs falling out its ass. Because, get this: what’s important is not the REST/RPC in the middle; it’s the state that exists at each end. And in the wonderful unpredictable hell that is non-deterministic computing, unless your management over time of all that distributed replicated state is solid as rock then your customers’ information WILL go to fuck. Frankly, the only thing ad-hoc RPC really does is enable lazy irresponsible incompetent coders to ship lazy irresponsible incompetent code that flings shit all over the world with absolutely zero effort. Having had to deal with other web apps’ RPC APIs in the past, I can confirm. They’re a bunch of fucking punks. At least expressing all interactions as state changes on a remote graph forces you to think in terms of state machines, and ensures a clear and complete set of rules for telling you to go 40x yourself when—whether through idiocy, malice, or the simple inherent reality of race/lock conditions—your request tries to fuck things up. Plus, if everyone’s following a common set of UX/UI patterns, after a while you can likely pull out a whole lot of reusable data formats that everyone can now adopt. Also, WTF does that Steve Yegge Java rant have to do with distributed system design? There’s one reference that matters here, and this is it: https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing https://en.wikipedia.org/wiki/Fallacies_of_distributed_compu... Normally I’d suggest that you’ve failed to see the forest for the trees, but I suspect in your case it’s because you’re standing in the ocean.