This is part three of the API design best practices series.
Once you have an understanding of what your API needs to be able to do in order to meet your developer’s requirements, it’s important to ensure that it remains as flexible and extendable as possible. Taking advantage of best practices not only means that your API will be familiar to developers, but also ensure that it remains fluid enough to extend and build on top of it in the future. Here are this week’s best practices to help keep your API agile:
Use Nouns as Resources
If you are building a REST API, be sure that you are using nouns as resources instead of verbs. Verbs are used more with JSON-RPC where you declare the action you are taking in the URL, such as:
As you can see, verbs are tightly coupled to a specific action and offer very little, if any flexibility. By using nouns, as recommended with REST and taking advantage of HTTP Action Verbs (such as GET, POST, PUT, etc) you can have loosely coupled resources that are able to accomplish multiple tasks and have new actions added at any time. Combined with hypermedia, this means that your users would be able to take advantage of any new actions immediately.
Your RESTful endpoints should look like:
Keep in mind that it is usually a good idea to use the plural form of the noun unless all available actions are explicit to the singular form.
CRUD stands for Create, Read, Update, and Delete. But put more simply, in regards to its use in RESTful APIs, CRUD is the standardized use of HTTP Action Verbs. This means that if you want to create a new record you should be using “POST.” If you are trying to read a record, you should be using “GET.” To update a record utilizing “PUT” or “PATCH.” And to delete a record, using “DELETE.”
It’s also important to understand the difference between PUT and PATCH, as PUT is used to perform a complete override of the record (if fields are not included, they are removed) where-as PATCH is used to update a record based on the information provided (or patch it with what you provide), leaving any fields not passed along intact.
Keep in mind there are several different HTTP Action Verbs available, and it’s easy to want to incorporate these new verbs and make your API new and different. However, when it comes to building an API, that’s the last thing you want to do. Utilize CRUD as that is what developers will be looking for when trying to utilize your API, and by deviating from it you are only make your API harder to use and maintain. Also keep in mind that not all browsers or servers support all the HTTP verbs currently out there.
Last but not least, do not mix HTTP Action Verb definitions – if you are telling your developers to make a POST, do not pass the data along as a querystring. That is not the definition of POST and will only cause more confusion for your users. Make sure you are staying consistent with the verb definition.
Use JSON (when possible)
These advantages have made it the format of choice for many developers and the leading format for use within REST APIs. Again, you’ll want to choose the format that is best for your clients, but in the event that you’re encoding objects as XML, I would strongly suggest also offering JSON as an alternative as the serialization is fairly quick and painless.
Keep in mind that one of the advantages to REST is that it is not limited to a single content type, and can return multiple formats if desired.
Use the Content-Type Header
In order to truly keep your API flexible and extendable for the future, it’s also important to build it not just for today’s leading formats, but also for whatever the future may hold. Until just recently XML was the format of choice for web services, but then JSON came along. Everyday new formats are being created and used, most notably YAML. For this reason it is important that your API does not constrain itself to only one format.
It’s perfectly acceptable to only have one format available if that meets your developer’s needs (for example, only taking advantage of JSON), but that doesn’t mean you shouldn’t be planning ahead. By taking advantage of the Content-Type header you can see what format of data your users are sending you, and in return send back that same format. For example, if a user sends a request using text/xml, you could send back an XML response while another user could send an application/json request and you could reply with JSON.
By building this functionality into your API to begin with, as new formats become available, or as you add high profile clients with special needs, you are now able to adapt to these new format requests without impacting other users, or other aspects of your API. This also means that you can stay on top of the technology curve without worrying about having to migrate users from one format to another, or from one API to another.
Ideally, your API’s architecture should be flexible enough to receive content in one format (as described by the Content-Type header) such as XML and return the response in another format based on the Accept header, such as JSON. Doing so is NOT a good practice, but it does reinforce just how decoupled your API should be from the technology stack, as well as how important incorporating view libraries to handle the output are. In other words, your API’s architecture should be versatile enough to do this, but it is probably best just to rely on the content-type instead of mixing data formats based on both the content-type and accept headers.
- What is Hypermedia
- Understanding HATEOAS