contents of this page
RESTful APIs¶
Principles¶
These are the principles that guided our API design:
- Aim to be RESTful: This has a controverial definition within the API community, but we followed some of the guidelines set forth in some of the REST resources listed here.
- Documented: We should document our API and interchange formats in a way that makes it easy for our users to find what they’re looking for and make the requests and interactions that they need to get their work done.
- Meaningful Error States: When there are problems finding requested data or if a service is down, we should have some well-established error states that can be handled gracefully by our clients.
- JSON as an interchange format: JSON is a lightweight and human-readable format. JSON’s only real drawback vs. something like XML is that there is no good way to define a JSON “schema” to document the formats formally. There is a jsonschema project to do this, but it’s still early days for that. So, we will just substitute a good schema for good documentation.
- Tested: The API should be tested, and, once it leaves “beta” state, it should be versioned and have a high degree of reliability and consistency.
- Language Bindings Included: RESTful API design really defines our wire format and mechanism for interacting with our server. But we should provide language bindings for various platforms to ease the ability to prototype applications atop the Parse.ly REST API.
Design Guidelines¶
Many of our design guidelines came from the excellent book by Leanard Richardson and Sam Ruby, RESTful Web Services, published by O’Reilly and the article A Brief Intro to REST.
We highly recommend you read that article and pick up a copy of the book if you ever need to design a service of your own!
Give every “thing” an ID¶
From “A Brief Intro to REST”:
Use URIs to identify everything that merits being identifiable, specifically, all of the “high-level” resources that your application provides, whether they represent individual items, collections of items, virtual and physical objects, or computation results.
Link things together¶
This doesn’t just mean that you actually have links (which is a corrolary of “everything has an ID”), but that when you return an object that references another object, you use the URL (link) to connect the two. “Use links to refer to identifiable things (resources) wherever possible.”
Use standard methods¶
What REST does is provide a “metamodel” for all the “things” in your web application. You could think of this as a widely-used base interface called “Resource”. If you were to model this in Java. you’d have e.g.
interface Resource {
Resource(URI u);
Response get();
Response post(Request r);
Response put(Request r);
Response delete();
}
Though things which implement the Resource interface can have a richer set of operations and behaviors, we should have reasonable actions that correspond to the above 4 operations. If we can map everything into those 4 (which sometimes correspond to the four actions in the CRUD model), all the better.
Communicate statelessly¶
This quote summarizes this best:
“First of all, it’s important to stress that although REST includes the idea of statelessness, this does not mean that an application that exposes its functionally cannot have state – in fact, this would render the whole approach pretty useless in most scenarios. REST mandates that state be either turned into resource state, or kept on the client.”
The way the Parse.ly team interprets this guideline is to “prefer stateless communication, otherwise, idempotence, otherwise, documentation!”. Obviously, you can’t make things stateless, but making them idempotent is probably a good idea, and if you can’t at least make it idempotent, then we better have documented it!
Guarantee Idempotence¶
Idempotence should be expected by our clients for many of our HTTP methods:
“GET is idempotent – if you issue a GET request and don’t get a result, you might not know whether your request never reached its destination or the response got lost on its way back to you. The idempotence guarantee means you can simply issue the request again. Idempotence is also guaranteed for PUT (which basically means “update this resource with this data, or create it at this URI if it’s not there already”) and for DELETE (which you can simply try again and again until you get a result – deleting something that’s not there is not a problem). POST, which usually means “create a new resource”, can also be used to invoke arbitrary processing and thus is neither safe nor idempotent.”
Multiple “Endpoints”¶
We assign unique URLs to user profiles, articles, sources, and everything else in our system. This follows the practice described here:
“In a RESTful approach, an application might add a few million customer URIs to the Web; if it’s designed the same way applications have been designed in CORBA times, its contribution usually is a single “endpoint” – comparable to a very small door that provides entry to a universe of resource only for those who have the key.”