Most mobile and distributed applications have an API to easily plug into and almost every application uses at least one. Everyone is doing it! But, not everyone is doing it right. Creating a rich API that can be easily scaled requires some planning and thinking. Most APIs developed these days, once deployed, can't be changed. Doing so usually results in breaking the client's code that rely on the API. While it's a good thing to remain consistent, we should give our APIs room for extension.
We believe API design should follow an open/closed principle which states "software entities should be open for extension, but closed for modification." Applying this principle will help your API evolve as the industry changes. Here are some of the best practices and pitfalls we've discovered to help you build a great API yourself.
Use nouns instead verbs (RESTful)
Verb resources (bad practice)
Developers may be tempted to be as descriptive as possible when structuring API resources. Take for instance the table above. Depending on how big your application is, using verbs will result in a huge list of URLs. It’s hard to keep track of such a list as a developer, but it’s even harder for your API consumers as they will need to dig into the documentation for every task. An API should be designed in such a way that users can guess or experiment successfully with the URLs.
Above is an example of how we can structure our resources better and make the API easier to use. We only need two resources, /photos and /photos/:id in conjunction with four HTTP verbs (GET, POST, PUT, DELETE) to be able to perform the operations in our previous huge list.
Use Transformers for data presentation
Another bad practice is querying the database and dumping everything out as an API response. Instead, I do strongly recommend the use of transformers over just dumping the database data to the world.
Transformers give you control over what data you actually output to your API consumers. With transformers we are certain that sensitive information is not displayed by mistake. Not only is it a security measure, transformers will help prevent API consumers code from breaking when your database schema changes.
While you can build your own transformers easily, I recommend Fractal (http://fractal.thephpleague.com/) if you are in the PHP world. With transformers you are afforded the benefit of serializing your data in a specific way, as well as embedding related resources within each other.
Use HTTP status codes
While there is more than a dozen status codes, for REST we only need to make use of 10 codes. Your API consumers will know how to respond to the errors since the status codes are a standard. You shouldn’t make your consumers just rely on the error messages to figure out how to proceed from an error. Below are the 10 status codes you need to use:
So don’t just return HTTP status code 200 for every request.
Error Codes and Messages
Apart from returning the correct HTTP status codes, it also helps to return custom error codes and verbose error messages for your API. These will go a long way if you have to offer support to your API consumers. Knowing the error code and message will make it easy to pinpoint the issue in your code.
Would you be happy to use an API without documentation? I’m hoping you answered “no”. So while documentation may be a painful process you just have to do it. A good resource documentation should at least include the following:
- Resource URL (https://api.example.com/photo/:id)
- Resource Information (Description, Response formats including JSON and XML, Requires authentication?)
- Parameters (specify required/optional) and give examples
- Example request
- Example result
Including usage examples and tutorials will be a plus.
Another important aspect in API design is authenticating and protecting our applications. Below are some strategies that you can use to authenticate clients who use your API.
HTTP Basic authentication
This is a standard HTTP authentication mechanism whereby clients supply username and password BASE64 encoded in the “Authorization” header.
Ouath2 comprise of the following two:
- user/client credentials to use in getting an access token
- Use the access token to access the API resources
However, since this involves transmitting access tokens and authentication credentials Oauth2 is only secure if used with TLS/SSL to encrypt data during transmission. You also, need to put into consideration storing the client credentials on clients like mobile applications. There is a debate about this as storing the credentials for Oauth2 on a mobile or desktop app doesn’t seem to be the most secure thing to do. If for instance, our client credentials get compromised, then the Oauth2 provider has to revoke the entire applications since we would have that information hard coded.
We have only scratched the surface here. There are a lot of techniques that we could talk about to make our APIs scalable and secure.