RESTful API Design
Overview
REST (Representational State Transfer) is the industry-standard architectural style for designing APIs. It forces strict mathematical uniformity, making your backend completely predictable for frontend developers. Instead of writing random URLs like /deleteUser or /getUsers, REST mandates that the URL strictly represents a Plural Noun (/users), and the HTTP Method strictly dictates the Action (GET to fetch, POST to create, DELETE to destroy).
Syntax
// A Perfectly RESTful Express Controller for the 'Users' Resource
// 1. GET (Fetch a collection of resources)
app.get('/api/users', (req, res) => { /* Return all users */ });
// 2. GET by ID (Fetch a single specific resource)
app.get('/api/users/:id', (req, res) => { /* Return user 42 */ });
// 3. POST (Create a brand new resource)
app.post('/api/users', (req, res) => { /* Insert into DB */ });
// 4. PUT (Completely replace a specific resource)
// OR PATCH (Partially update a specific resource)
app.patch('/api/users/:id', (req, res) => { /* Update user 42's email */ });
// 5. DELETE (Destroy a specific resource)
app.delete('/api/users/:id', (req, res) => { /* Remove user 42 */ });Common Pitfalls
- Using Verbs in the URL. A URL like
/api/users/createNewUseris a severe violation of REST principles. The URL is the Noun (/users), the HTTP method (POST) is the Verb. The combination ofPOST /usersnatively implies creation. - Nesting too deeply.
GET /api/users/42/posts/99/comments/5is incredibly difficult to maintain and implies complex database joins. The industry standard is to flatten relationships. Just useGET /api/comments/5to fetch that specific comment, regardless of who owns it.
Interview Questions
PUT request and a PATCH request in REST?PUT is Idempotent and represents a COMPLETE replacement of a resource. If you PUT an object with only a firstName, it should logically delete the lastName to match the exact payload. PATCH represents a PARTIAL update, meaning it surgically updates only the fields provided in the payload, leaving the rest untouched.
Real-World Example
Implementing proper RESTful pagination using Query Strings, rather than altering the URL path.
// Correct RESTful Pagination
// GET /api/articles?page=2&limit=50
app.get('/api/articles', async (req, res) => {
// Default to page 1, limit 20
const page = parseInt(req.query.page) || 1;
const limit = parseInt(req.query.limit) || 20;
const offset = (page - 1) * limit;
const articles = await db.query('SELECT * FROM articles LIMIT $1 OFFSET $2', [limit, offset]);
res.json(articles);
});Check Your Knowledge
Test your understanding of RESTful API Design with these quick questions.