6 Things You’re Doing Wrong with Your REST API
A simple CRUD REST API can be quick to build, but there are a few gotchas to watch for.
1. You Don’t Have a REST API
Many frameworks support building your front end as server side views and sending the rendered HTML to the client. This makes it very easy and fast to build a web application. However, the biggest drawback is your front end is tightly coupled to your back end. What will you do when you want to create a mobile or desktop app? You’ll have to duplicate your back end logic and create an API for the new front end. Instead, do it right from the beginning and create a web API.
The main idea is to decouple your front end from your back end. Creating a REST API is just one way to do this. There are other options as well, such as a GraphQL API, SOAP API, or using a BaaS provider. Which one to choose will depend on time, budget, tech stack, and knowledge.
2. You’re not Versioning your API
APIs inevitably change and without versioning, you’ll be faced with upset users forced to update because of a breaking API change. Instead, if you have:
GET /v1/lists
And then create:
GET /v2/lists
for your breaking change, users with an older front end will still function while users on a newer front end can utilize the new endpoint.
3. You Have Nested Resources
A common approach to designing REST APIs is to nest related resources like:
GET /v1/lists
GET /v1/lists/1/tasks
GET /v1/lists/1/tasks/1
Nested resources make the relationship between resources clear; task is a sub-resource of list. This is nice in theory, but, in practice, makes the API more limited because there is no way of doing an operation on sub-resources across multiple parent resources. For example, you wouldn’t be able to get all tasks past due.
A flat API, such as:
GET /v1/lists
GET /v1/tasks?list_id=1
GET /v1/tasks?task_id=1
will allow you to do the same and more (as long as you support filtering).
4. You’re Filtering Wrong
The first thought when building an API is to automatically filter it for the end user to only show their resources. For example, the:
GET /v1/lists
endpoint would only return results where the current user is the owner. This makes sense, but it’s restrictive and not flexible for an admin interface.
You should only automatically filter out resources a user should absolutely never be able to see. Then, add filtering options so the front end can choose what to filter out. Assuming the current user’s ID is 1, the front end can then call:
GET /v1/lists?owner=1
to get their task lists. For a regular end user, the results would be the same as without the filter, but, for an admin, the results would correctly filter to what the front end wants to display. The admin interface can, then, call:
GET /v1/lists
to get all task lists.
5. You’re Not Paginating Results
It’s easy to overlook pagination, but it will bite you later on when your app slows to a halt because there is too much data being returned or too much data to display. If you wait until then, you’ll be in a mad rush to rework your front end and back end to support pagination.
Offset based pagination is a common approach to implementing pagination. For example:
GET /v1/tasks?offset=20&limit=10
would skip the first 20 tasks and return only 10 tasks. If you want to support jumping to a certain page, you’ll also need to return the total number of records so the front end can determine how many page numbers to show.
In addition to offset based pagination, there’s cursor based pagination which is a bit more complicated, but can perform better for larger data sets.
6. You Have Bad Documentation
If you expect others to consume your API, you need to provide up to date documentation. Stale or non-existent documentation will make it more difficult for anyone not familiar with the original codebase to understand what your API can do. Ideally, your API should be documented with an OpenAPI spec (previously known as Swagger) and the documentation should be inline with your code.
OpenAPI is a popular standard for documenting REST APIs with a JSON or YAML file. With the spec, you can document what endpoints are available, what parameters each endpoint takes, and what the endpoint returns. There are also renderers available to give your documentation a nice interface. Swagger UI and ReDoc are two popular ones.
Some frameworks and libraries allow you to write your documentation inline with your code and generate the OpenAPI JSON or YAML. Inline documentation is the best approach because it is less likely to become stale.
Key Takeaways
REST APIs are pretty standardized, but people often overlook some aspects while they focus on building fast.
- Have an API
- Version your API
- Don’t have nested resources
- Support filtering
- Support pagination
- Document your API
Are you already doing these things? Are there any other aspects that bit you down the line? Let me know in the comments below!