API Design Tips and Pitfalls

Most mobile and distributed applications have an API to plug into quickly, and almost every application uses at least one. Everyone is doing it! But only some people are doing it right. Creating a rich API that can be easily scaled requires planning. Unfortunately, most APIs developed these days, once deployed, can't be changed. Doing so usually breaks the client's code that relies on the API. So while it's good to remain consistent, we should give our APIs room for extension.

We believe API design should follow an open/closed principle: "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 of verbs (RESTful)

Verb resources (bad practice)

MethodURI
GET/getAllPhotos
POST/addPhoto
PUT/updatePhoto
DELETE/deletePhoto
PUT/updateAllPhotos
DELETE/deleteAllPhotos
GET/getPhoto

Developers may be tempted to be as descriptive as possible when structuring API resources. Take, for instance, the table above. Depending on your application's size, using verbs will result in a massive 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 so that users can guess or experiment successfully with the URLs.

Noun resources

ResourceGETPOSTPUTDELETE
/photosReturn list of all photosAdd a new photoBulk update all photosDelete all photos
/photos/3Return a specific photoerrorUpdate a specific photoDelete a specific photo by identifier

Above is an example of how we can structure our resources better and make the API easier to use. For example, 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 colossal list.

Use Transformers for data presentation

Another bad practice is querying the database and dumping everything as an API response. Instead, I recommend using transformers over dumping the database data to the world.

Transformers give you control over what data you output to your API consumers. With transformers, we are confident that sensitive information is not displayed by mistake. Not only is it a security measure, but transformers will also help prevent API consumers' code from breaking when your database schema changes.

While you can build your transformers easily, I recommend Fractal if you are in the PHP world. With transformers, you are afforded the benefit of serializing your data in a specific way and embedding related resources within each other.

Error handling

Use HTTP status codes

While there are more than a dozen status codes, we only need ten codes for REST. Your API consumers will know how to respond to the errors since the status codes are a standard. It would be best if you didn’t make your consumers rely on the error messages to determine how to proceed from an error. Below are the ten status codes you need to use:

200The request has succeeded
201Resource successfully created
204Request fulfilled but no content returned
304Request not modified
400Bad request. Reqeuest can not be understood by the server due to malformed syntax
401Unauthorized. The request requires user authentication
403Forbidden
404Not found. Server can not find requested resource
409Conflict. Request can not be completed due to conflict with the current state
500Internal Server Error

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.

Documentation

Are you happy to use an API without documentation? I’m hoping you answered “no.” So while documentation may be painful, you have to do it. Good resource documentation should at least include the following:

  • Resource URL (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.

Including usage examples and tutorials will be a plus.

Authentication

Another critical aspect of API design is authenticating and protecting our applications. Below are some strategies you can use to authenticate clients using your API.

HTTP Basic authentication

This is a standard HTTP authentication mechanism whereby clients supply a username and password BASE64 encoded in the “Authorization” header.

Oauth2

Ouath2 comprise of the following two:

  1. user/client credentials to use in getting an access token
  2. 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 consider storing the client credentials on clients like mobile applications. There is a debate about this, as keeping the credentials for Oauth2 on a mobile or desktop app isn’t the most secure thing to do. If, for instance, our client credentials get compromised, then the Oauth2 provider has to revoke the entire application 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.