RESTful API Design Principles
Mind Map Summary
- REST (REpresentational State Transfer): An architectural style for designing networked applications, not a strict protocol.
- Core Idea: Treat everything as a Resource.
- Key Constraints:
- Client-Server: Separate the UI (client) from the data storage (server).
- Stateless: Each request from the client must contain all information needed to complete the request. The server holds no client session state.
- Uniform Interface: The cornerstone of REST. This is what makes it work.
- Identify resources via URI: e.g.,
/api/posts/123
. - Manipulate resources via representations: The client sends a representation (e.g., JSON) of the resource’s desired state.
- Use HTTP Verbs as Actions: Use
GET
,POST
,PUT
,DELETE
to operate on the resource. - HATEOAS (Hypermedia as the Engine of Application State): Responses should include links to other possible actions (e.g., a
post
object could contain a link to get itscomments
).
- Identify resources via URI: e.g.,
- Practical Design Principles
- URIs should use nouns, not verbs:
- Good:
/posts/123
- Bad:
/getPostById?id=123
- Good:
- Use Plural Nouns for Collections:
/posts
, not/post
. - Use HTTP Verbs Correctly:
GET
: Retrieve data (safe and idempotent).POST
: Create a new resource (not idempotent).PUT
: Replace a resource completely (idempotent).PATCH
: Partially update a resource.DELETE
: Remove a resource (idempotent).
- Use HTTP Status Codes Semantically:
200 OK
: General success.201 Created
: A new resource was successfully created.204 No Content
: Success, but there is nothing to return (e.g., after aDELETE
).400 Bad Request
: The client sent invalid data.401 Unauthorized
: The client is not authenticated.403 Forbidden
: The client is authenticated, but not authorized to perform the action.404 Not Found
: The requested resource does not exist.
- URIs should use nouns, not verbs:
Core Concepts
1. Resources
In REST, the focus is on the things or nouns in your system, which are called resources. A resource could be a product, a user, an order, or a blog post. Each resource should have a unique identifier, which is its Uniform Resource Identifier (URI). For example, /api/users/123
is the unique URI for the user with an ID of 123.
2. Statelessness
This is a critical constraint. The server must not store any information about the client’s session between requests. Every request from the client must be self-contained and include all the necessary information (e.g., authentication tokens, identifiers) for the server to process it. This makes the API highly scalable, as any server instance can handle any client request without needing shared session state.
3. Uniform Interface
This is what makes REST so powerful and consistent. It’s a set of rules that ensures the API is predictable.
- Use HTTP Verbs for Actions: Instead of creating URIs like
/createUser
or/deleteProduct
, you use the built-in HTTP methods to define the action you want to perform on a resource URI.POST /users
-> Create a new user.DELETE /products/45
-> Delete the product with ID 45.
- Idempotency: An operation is idempotent if making the same request multiple times produces the same result as making it once.
GET
,PUT
, andDELETE
are idempotent.PUT /products/123
with the same data twice is the same as doing it once.DELETE /products/123
twice is the same as doing it once.POST
is not idempotent; callingPOST /products
twice will create two new products.
Practice Exercise
Design the REST API endpoints for a blog post resource. Show the URLs and HTTP verbs for: 1) Getting all posts, 2) Getting a single post, 3) Creating a new post, 4) Updating a post, 5) Deleting a post, and 6) Getting all comments for a post. Justify your choices.
Answer
Here is a standard, RESTful design for the blog post resource:
-
Get all posts
- Endpoint:
GET /posts
- Justification:
GET
is the correct verb for retrieving data./posts
uses a plural noun to represent the collection of all post resources.
- Endpoint:
-
Get a single post
- Endpoint:
GET /posts/{postId}
- Justification: This follows the pattern of
/{collection}/{resourceId}
. It uniquely identifies a single post resource.
- Endpoint:
-
Create a new post
- Endpoint:
POST /posts
- Justification:
POST
is the standard verb for creating a new resource. The request body would contain the data for the new post (e.g., title, content). A successful response should be a201 Created
status code with aLocation
header pointing to the URI of the newly created post (e.g.,Location: /posts/124
).
- Endpoint:
-
Update a post
- Endpoint:
PUT /posts/{postId}
orPATCH /posts/{postId}
- Justification:
PUT
is used to completely replace the resource. The request body must contain the entire post object. If a field is omitted, it would be set to null. This is idempotent.PATCH
is used to partially update a resource. The request body would only contain the fields that need to be changed (e.g., just thetitle
). This is the more flexible and often preferred method for updates.
- Endpoint:
-
Delete a post
- Endpoint:
DELETE /posts/{postId}
- Justification:
DELETE
is the standard verb for removing a resource. A successful deletion should return a204 No Content
status code.
- Endpoint:
-
Get all comments for a post
- Endpoint:
GET /posts/{postId}/comments
- Justification: This is a nested resource. The URI clearly expresses the relationship: we are getting the
comments
collection that belongs to the specific post identified by{postId}
. This is the standard RESTful way to represent parent-child relationships.
- Endpoint: