Crafting Restful APIs

Resources

Resources represent an entity, for example a car, building, person, etc. I usually use name my resources as plural, as most of the time I’m working with a collection of entities.

Its easiest to think of your API like a database, it is used to create, read, update or delete data.

HTTP Verbs

HTTPS verbs describe the action thats going to take place, for example: - GET: Used for retrieving resources - POST: Used for creating resources - PUT: Used for updating resources - DELETE: Used for deleting resources

Example

GET    /cars - Return a collection of all cars
GET    /cars/:id - Return a car by ID
POST   /cars - Creates a new car in the collection
PUT    /cars/:id - Updates a existing car
DELETE /cars - Deletes all cars
DELETE /cars/:id - Deletes a car

Objects

In the previous section we talked about using an id to perform operations to a specific entity in a collection. This id should also be contained within the JSON object when we get it from the server, for example our car resource might return the following:

GET /cars/2

{
"id": 2,
"brand": "Tesla",
"model": "Model 3"
}

Now that we have that model, we might assign to a variable car. We might want to update the car variable.

car.brand = "Model X"

Now we want to update the record on the server, we can do it in JavaScript as follows:

const response = await fetch("/cars/" + car.id, {
method: "PUT",
body: JSON.stringify(car)
});

As you can see from the example, ensuring the resource id and object id (car.id) matches is important.

Nesting Resources

Some resources relate to others, for example a car has many parts. Both cars and parts are resources. Parts can be nested under cars, like follows:

/cars/:car-id/parts/:part-id

e.g.
/cars/2/parts/10

A new part for a car with id 2 can be created as follow:

POST /cars/2/parts

How it all works together

URL (Universal Resource Locator)

Extra: Versioning

Over time your API might change with requirements, this could potentially break compatibility with older versions of the API. Some times there might be a need to run the old version alongside the new version, allowing people to use the legacy API before they transition to the new one.

A nice way to manage this is to version the API. If you already do semantic versioning, you can use the major version for this (as changing the major version implies breaking backwards compatibility).

Versioning can look like the following:

/v1/cars
/v2/cars/

Conclusion

Following certain patterns makes it much easier to create APIs. Designing straight forward APIs also makes it easier for the people consuming the APIs.

In summary, this can be done by: - Naming of resources - Use HTTP verbs - Nest related resources

Further Reading