This is part two in a three part series about the history of API design.
- Before There Was REST
- The Arrival of REST
- GraphQL and the Future
In the last post, we talked about the birth of the internet, HTTP, CORBA, SOAP, XML, and JSON. Now let’s fast forward to…
The Arrival of REST
2000, Irvine, California: Roy Fielding obtained his doctorate in computer science with a dissertation that proposed a new HTTP API protocol called Representational Transfer of State—REST.
So what’s the point of REST? Most developers will mutter something about verbs and then show you this chart:
Developers tend to recognize RESTful routes as endpoints that make use of several resource (noun) based URLs that indicate what they’re trying to do with HTTP verbs. SOAP, by contrast, makes use of one URL and requests indicate what they want to do with request bodies.
The RESTful routes chart is fantastic, but it’s also a huge simplification of the point that Fielding’s dissertation meant to convey. A closer summary of the immediate benefit of the REST protocol sounds something like this:
So far, things like CORBA, SOAP, and other RPC protocols were based on the faulty premise of defining with high precision the bits of data sent over the wire and back. Things that are highly precise are the easiest to break.
REST is based on the idea that you should send data but also information on how to consume the data…
The format of data can be dictated by media types, something that made it easy for browsers to handle HTML, image files, PDFs, etc. Browsers were coded once, long ago, to render a PDF document inline including a button to optionally save. Done and done. HTML pages are run through a different parser. Image files are similarly rendered without needing more and more upgrades to the browser. With a rich suite of standardized media types, web sites can evolve rapidly without requiring an update to the browser.
REST’s big breakthrough was not, in fact, using http verbs. The flexibility to dictate how a response should be handled differentiated it from SOAP and CORBA. We can push this lever further by having our HTTP responses include links to related activities that a developer may want to do with the information from this response.
HATEOAS: Worth a mention, but not its own separate thing
We call the links hypermedia (because God forbid we leave it at ‘links’). Programmer Leonard Richardson proposed that including those links in responses constitutes the highest level of advancement in his eponymous maturity model of API RESTfulness.
We call the inclusion of links in responses hypermedia as the engine of application state—HATEOAS (pronounced HAY-tee-yos by some developers, HAY-tee-yo-az by other developers, and unnecessary jargon by this developer).
Here’s what it might look like in an API response:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
response to GET 'awesomeprogrammers.com/latanya_sweeney' | |
{ | |
"name" : "Latanya Sweeney", | |
"links" : [ | |
"summary" : { | |
"verb" : "GET", | |
"url" : "http://latanyasweeney.org", | |
"authenticate" : false | |
}, | |
"headshot" : { | |
"verb" : "GET", | |
"url" : "http://latanyasweeney.org/Sweeney6.jpg", | |
"authenticate" : false | |
}, | |
"twitter" : { | |
"verb" : "GET", | |
"url" : "https://twitter.com/latanyasweeney", | |
"authenticate" : false | |
}, | |
"update" : { | |
"verb" : "PUT", | |
"url" : "awesomeprogrammers.com/latanya_sweeney", | |
"authenticate" : true | |
} | |
] | |
} |
For about two years, REST percolated through academia to corporate-landia. In 2002, SalesForce and Ebay released APIs that are sort of RESTy. APIs thus became a customer-facing product and not just an in-house thing to be used by the company that made them.
Then in 2003, we got Rails. Rails is a web framework written in Ruby that aims to make it easy and quick for developers to ramp up and add features to their apps. Compared to its contemporaries in the early 2000s, it did just that, so it quickly spread through the upstart programming community.
Rails is what’s called an opinionated framework—it evangelizes, with its copious defaults, a preferred way to write web apps. Its default endpoint strategy? You guessed it: REST. Rails exposes a lot of web developers to the REST protocol: for many of those developers, it was (and is) their first and only protocol.
As the years ticked by an external API became an expectation for software products instead of a nice-to-have, as demonstrated by the public lament about Facebook’s lack of an API when it launched in 2004. People hacked together crawler-based APIs for it until it released an official API in 2006. Twitter took less than a year after its launch to release an API. Those APIs followed the zeitgeist: RESTfulness.
Today, REST is popular: an estimated 70% of public-facing APIs are REST-ish, which is about the percentage it takes to get this bandwagon effect in the programming community of “everyone is doing it” and “let’s do this because it’s what I know,” which factors into developers’ decisions about what to do more than you want to know (and for good reason—when the business is pushing an already-unrealistic deadline and nobody is saying “no”, developers don’t have time to learn new stuff. They just have to execute.)
But there’s an interesting bifurcation buried in these numbers: a lot of public-facing, open-source, and startup APIs followed REST, while the larger, older companies—the ones that caught onto web requests back in the 90’s and before—have accustomed themselves to building systems on a single-endpoint protocol: SOAP (or at least SOAP-inspired).
You see this in the programming populace: young upstart programmers who have worked for young upstart companies think that REST is the thing, and they sometimes look down their noses at other options. They don’t see that they’re gleefully wrapping themselves in the exact same haughty resistance to new information for which they disparage their graying, pocket-protector programmer predecessors.
What do RESTful requests look like?
Something like this:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
POST request to 'awesomeprogrammers.com/sessions' | |
{ | |
"userName": "Ada Lovelace", | |
"password":"WerdToThePass" | |
} |
You’re calling different resource-oriented URLs with different HTTP verbs to get what you want. You GET /apples to get all the apples. You GET /apples/1 to get the apple with an ID of 1. You POST /apples to create an apple, then PUT /apples/2 to update the apple with an id of 2. You delete the apple with DELETE /apples/2.
REST is a protocol, not an implementation, and it can be implemented with either XML or JSON (or any data transfer format). Nowadays, JSON is more popular because it looks nicer and because people think it is faster than XML. The faster thing checks out in a lot of contexts, but it depends on the mapper in the specific library you are using.
So when do you use REST, and when do you use SOAP?
REST is a great fit for creating, reading, updating, and deleting records from a database table: in this way, it functions as an across-the-internet extension for your database query language. It’s not such a natural fit for other operations like aggregating, summarizing, batching, or checking data. Developers sometimes make an effort to jam it in: for example, we’ll get a summary of all our apples with GET /apples/summaries. But we’re reaching when we do this, because this is non-standard: we have to document this call for folks to know it’s there. And if we have to document it anyway, we might as well call it /summarize, even though that’s a verb and so violates the holy RESTfulness of making our URLs with nouns.
API design is a bit of an art, and reasonable people will differ on when to do what. As you’ll see in the next post in the series, my tabula rasa approach involves determining exactly what the client needs and choosing feature combinations that make sense for the client. Maybe that approach conforms to a protocol, and maybe it cherry-picks from several. But while we’re on the subject, I did find this slide by matrixpp on blogspot that provides some additional food for thought:
In the next post, we’re traveling forward another 15 years to discover that the newest approaches might not be so new after all.
If you like this kind of thing, you might also like:
Computer History: IBM Selectric
“REST is a protocol, not an implementation”
Well…REST is actually a set of architectural constraints levied to make it possible for your services to scale to web level.
On the biggest things to make your service RESTful is to NOT delete a field! If you alter your services “name” field and replace it with “firstName” and “lastName”, you should STILL present the original “name” field. That will support existing clients and not break them.
This is the type of stuff that dodges the brittle nature of CORBA and SOAP. CORBA and SOAP were two rigidly defined protocols that can’t handle optional fields that like. Hence, the reason they came up with versioned APIs.
With REST, older clients can, by default, ignore newer, unknown fields. And newer components can “upgrade” older fields to integrate with new stuff. All of this makes for a more fluid, scaleable solution.