Tips for writing APIs

:  ~ 2 min read

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:
{
	"id": 1234,
	"name": "Roland Leth"
}
// vs
{
	"user": {
		"id": 1234,
		"name": "Roland Leth"
	},
	// Room for new data here
}