DEV Community

Cover image for REST API Design Rules

REST API Design Rules

Ezekiel on June 01, 2024

Why is it important to write clean REST-API Designs In today's interconnected world, well-designed REST APIs are the backbone of efficie...
Collapse
 
adaptive-shield-matrix profile image
Adaptive Shield Matrix

Don't write REST-Apis.
Just write regular APIs with GET and POST.
The REST standard is outdated and a historical fossil.
No one can remember if you PUT, PATCH or POST changes.

REST suffers heavily if you want to design your business process: how do you start/initiate a process. Is it PUT, PATCH or POST, is it a separate Resource (or an virtual resource that does not exist as separate entity in your db to satisfy REST guidelines?) or an update to an existing one? -> There are no right answers and trying to fit your business process into a REST-API feels like trying to trying fit a sphere into a square hole -> it just doesn't fit.

Just write good docs using swagger.io/tools/swagger-ui/ or other/similar tools.
Good docs are 100x more important than adhering to an easily misunderstood, wrongly interpreted, outdated standard that no-one uses in the real world (or implements it wrongly).

Use

  • GET - for reads, allows leveraging browser build-in caching
  • POST - for writes, modifications and deletion
Collapse
 
dko1905 profile image
Daniel

Write REST-APIs
Using a custom, in-house API-convention makes APIs unnecessarily complex and knowing if POST is used for creating, updating or deleting items could depend on the API. This uncertainty will slow down developers and make APIs harder to understand.

Don't write REST-Apis.
Just write regular APIs with GET and POST.
The REST standard is outdated and a historical fossil.

The HTTP-standard, TCP-standard and even the x86 CPU-architecture are all old standards. That doesn't mean, that they are obsolete. I would even go so far to say, that older standards have proven their resilience and practicality by still being around today.

No one can remember if you PUT, PATCH or POST changes.

I think of REST-methods as being aligned with the CRUD-model. Each CRUD-operation directly corresponds to one HTTP-method.

CRUD HTTP
Create POST
Read GET
Update PUT
Delete DELETE

Additional HTTP-methods, like PATCH, exist to allow partial updates and other complex mutations, and remembering how to use these 5 standard HTTP-methods in REST-APIs is not very hard.

Good docs are 100x more important than adhering to an easily misunderstood, wrongly interpreted, outdated standard that no-one uses in the real world (or implements it wrongly).

Good docs are always good but many developers make assumptions before reading the documentation (if they read it). Assumptions like POST-operations won't accidentally delete data. The assumptions are not that the API strictly follows the REST-standard but that it is REST-like. These REST-like APIs can be found everywhere in the real world. Just take a look at the API-calls by dev.to.

Collapse
 
bukajsytlos profile image
bukajsytlos

first of all, these "REST" guidelines are not RESTful. they are HTTP API guidelines

Collapse
 
micha_maj_1cbf21bc8a63e1 profile image
Michał Maj

When I think about RESTful APIs, I compare them to OOP. It is common practice to combine OOP with functional programming, which is why what you are saying reminds me of combining REST with a SOAP approach. But you still need to know their rules.

Collapse
 
schmoris profile image
Boris

Is there any disadvantage of using singular for endpoints that return a single entity guaranteed and plural for collection endpoints, e.g.:

/api/v1/users/name/:name but also /api/v1/user/ident/:ident

I guess consistency is key, but maybe there's something I don't see yet :-)

Collapse
 
ezekiel_77 profile image
Ezekiel

Hey there! Thanks for the comment, that's a tricky one! You're right, consistency is king in the API world, but there's always room for debate

Here's the thing: some folks like plural nouns for collections /users because it's super clear they hold a bunch of stuff. Plus, it kinda aligns with how developers expect things to work (think lists and arrays).

On the flip side, singular nouns for single things /user can be shorter and feel more specific, especially for resource names that are already longwinded. But the downside is it might be a little confusing at first for developers expecting a whole bunch of stuff back.

Honestly, there's no one-size-fits-all answer. The best bet is probably to stick with plural for collections /users and singular for single things /user just to keep things clear and consistent across your entire API. That way, developers won't have to scratch their heads wondering what's what.

Of course, if you have a really good reason to go against the grain (like super short resource names), just make sure everything is consistent! And hey, document your approach clearly in your API docs to avoid any future head-scratching.

Thanks again for bringing this up, it's definitely a point to consider when designing your API!

Collapse
 
syeo66 profile image
Red Ochsenbein (he/him) • Edited

I think it might start to get hard if you have to decide what the plural of 'person' is. Is it 'persons' or 'people'?

Collapse
 
ezekiel_77 profile image
Ezekiel

😂

Well in most systems its usually users not persons or people

Thread Thread
 
syeo66 profile image
Red Ochsenbein (he/him)

Not every person is a user.

Collapse
 
shyam_10 profile image
Shyam raj

I think you forget about versioning. Versioning is so much important in api design with backward compatibility , because if we want to add a new feature to the api, the end points should not change (consistent naming represents a well designed api). If the endpoints changes it will affect user experience. So by adding versioning(with new feature) the users who dont need the new features can still use the old api end point, and also those who needs new features can use the versioned api

Collapse
 
ezekiel_77 profile image
Ezekiel

Thanks for your insightful comment! You're absolutely right, versioning is a crucial aspect of REST API design, and I apologize for not including it in the initial post.

Collapse
 
peteraba profile image
Peter Aba

There are more "complete" guidelines out there which take care of a lot of edge cases. For example the Zalando API Guideline. I'd usually start with something like this and define my own rules on top of it for anything that might be used out in the wild.

Collapse
 
algorodev profile image
Alex Gonzalez

Great article! I just recommend you to finish your articles with a conclusion.

Collapse
 
ezekiel_77 profile image
Ezekiel

⭐ That's a fantastic suggestion! I'll definitely craft a conclusion to solidify the key takeaways

Collapse
 
honza_moravec_16974f10c32 profile image
Honza Moravec

yeah you did it 🦾🤖

Collapse
 
suyash_patil profile image
Suyash Patil • Edited

Great explanation, and I got to know where am I lacking to make a perfect rest API. Still I'm a beginner in the world of API's but this helps a lot.

Collapse
 
thienvu2103 profile image
Le Dinh Thien Vu

Hi folks, I have a minor question.
For example. I have a collection Groups, and 1 user can join/leave the a group. so what should an API be?
Is it PATCH? localhost:8080/v1/groups/join and localhost:8080/v1/groups/leave ?
or just a localhost:8080/v1/groups and the query param will be a flag to determine join or leave?

Collapse
 
ezekiel_77 profile image
Ezekiel

There is also another type of resource called Controller Resources which is used to perform actions that cannot be logically mapped to any of the http methods

So for the localhost:8080/v1/groups/<groupid>/leave will be a POST as well as the join endpoint

Collapse
 
aneroid profile image
Anirudh Dutt • Edited

If the user is triggering the join or leave action, then it should be a PUT request: PUT /v1/groups/{groupId}/join

PUT is safe to repeat without further side-effects (aka idempotent). A user joining a group they have already joined doesn't "extra-join" them.

Similarly, leaving the group would be: PUT /v1/groups/{groupId}/leave

Collapse
 
arnoldschan profile image
Arnold Samuel Chan

Great article!
I personally use django restframework, and CRUD endpoints are ready out of the box. Anyone know is there any alternative library for javascript? Express feels like Python's flask, and everything feels manual.

Collapse
 
ezekiel_77 profile image
Ezekiel • Edited
Collapse
 
sirthaven profile image
Jakub Serafin

I don't like this kind of articles. it has bunch of advices, but without supporting them with any explanation why. Without this those are not best practices, but just bunch of magic rituals and spells.

Collapse
 
mrsharpp profile image
Amir Alam • Edited

exactly, just blindly following the rules without any understanding