---
title: "Tips for writing APIs"
slug: tips-for-writing-apis
section: tech
date: 2017-08-27T18:18:00.000Z
canonical: https://roland.leth.ro/blog/tech/tips-for-writing-apis
---

I'd like to leave a few tips that I think are adamant in writing good APIs. I've come across all of these mistakes, and they are a **pain** to deal with. Some more than others, but all decrease the enjoyability of working with them.

1. First and foremost, be consistent. This might be *the* most important tip I would give, and will be the most detailed one:
	- some cases are more broadly used, but, ultimately, it doesn't matter if you use `camelCase`, `PascalCase`, or `snake_case`, just use the same kind everywhere;
	- the above point goes for naming endpoints too; don't have one endpoint `reference-data` and another `public_posts`;
	- when two endpoints return the same kind of object(s), it's a good idea for the key of said object(s) to be the same (the same goes for all of its keys). For example, if an endpoint has a user under the key `user`, other endpoints that contain a user should not have them under the key `person`;
	- if you have a kind of object under a key, and there's a possibility of it not existing, do not return any other kind of object under that key - either `nil`, `null`, or empty object (at the worst case). For example, do not return an empty array where you'd usually find a dictionary;
	- if most of your endpoints have one kind of structure, use it everywhere. For example, if three endpoints have a root dictionary, don't make your other two endpoints have a root array;
	- if you have some endpoints making use of `REST` methods, for example `DELETE /users/1`, don't have other endpoints use a path component for the same functionality, for example `GET /posts/1/delete`;
	- if you have several endpoints that can be queried with the same parameters, use the same names in all places. If one endpoint expects `query` and `pageSize`, don't have other endpoints expect `q` and `ps`;
	- for the same problem, always return the same `HTTP` code, for all endpoints. For example, if a resource can not be found, don't return `400` for one endpoint and `404` for another.
2. If you're writing `REST` APIs, use its  methods instead of path components:
	- `GET` to get a resource;
	- `POST` to create, instead of `GET /users/create`;
	- `PUT` to update, instead of `GET /users/1/update`;
	- `DELETE` to delete, instead of `GET /users/1/delete`;
3. Use versioning: `/v1/users/1`. Even if you're absolutely sure you won't need it, it's still good practice. *Never say never*.
4. Always have a container dictionary at the root level. This leaves room for adding new data in the future, while keeping the endpoint backwards-compatible. You might say that we can just create a new version for this endpoint, and you'd be right most of the time; but there are cases where you do not want to/can not create a new version yet:

```json
{
	"id": 1234,
	"name": "Roland Leth"
}
// vs
{
	"user": {
		"id": 1234,
		"name": "Roland Leth"
	},
	// Room for new data here
}
```