Representational State Transfer (REST) is an architectural style that defines a set of constraints for creating web services. A well-designed REST API is predictable, easy for developers to understand, and consistent. The two core pillars of good design are how you structure your resources and how you use HTTP status codes to communicate outcomes.

Designing Your Resources (The Nouns)

Think of resources as the "nouns" of your API. They are the entities your API provides access to, like users, products, or articles. The key principle is to use nouns in your URIs (Uniform Resource Identifiers), not verbs.

Best Practices for Resources:

  • Use Nouns, Not Verbs: Your endpoints should represent entities. The action is determined by the HTTP method (GET, POST, PUT, DELETE).
  • Bad: /getUsers, /createNewArticle
  • Good: /users, /articles
  • Use Plurals: For collections of resources, always use the plural form. It keeps your API consistent.
  • Bad: /user/123
  • Good: /users/123
  • Use Nesting for Relationships: If a resource is related to another, express this hierarchy in the URI. For example, to get the comments for a specific article:
  • Good: /articles/54/comments
  • Also good for filtering: /comments?articleId=54
  • The nested approach (/articles/54/comments) is generally preferred for clear hierarchical relationships.

Using HTTP Methods (The Verbs)

HTTP methods define the action you want to perform on a resource.

MethodActionExample URIDescriptionGETRead/users, /users/123Retrieve a list of resources or a single resource.POSTCreate/usersCreate a new resource. The payload is in the request body.PUTUpdate/Replace/users/123Completely replace an existing resource.PATCHPartial Update/users/123Partially modify an existing resource.DELETEDelete/users/123Remove a resource.

Export to Sheets

Using HTTP Status Codes (The Response)

Status codes are crucial for letting the client know the outcome of their request. Using them correctly makes your API transparent and easy to debug.

  • 2xx Success Codes: The request was successful.
  • 200 OK: The standard success response for GET, PUT, PATCH.
  • 201 Created: The request was successful, and a new resource was created (used with POST). The response should also include a Location header pointing to the new resource's URL.
  • 204 No Content: The server successfully processed the request but has no content to return (often used with DELETE).
  • 4xx Client Error Codes: The client did something wrong.
  • 400 Bad Request: The server cannot process the request due to a client-side error (e.g., malformed JSON).
  • 401 Unauthorized: The client must authenticate to get the requested response. They haven't provided credentials or the credentials are bad.
  • 403 Forbidden: The client is authenticated, but they do not have permission to access the resource.
  • 404 Not Found: The server cannot find the requested resource.
  • 5xx Server Error Codes: The server failed to fulfill a valid request.
  • 500 Internal Server Error: A generic error message given when an unexpected condition was encountered on the server. Don't reveal sensitive stack traces!

Code Snippet: Express.js Example

Here’s a simple example in a Node.js Express server showing how to handle a POST request to create a user and return the correct status code.

JavaScript


import express from 'express';
const app = express();
app.use(express.json()); // Middleware to parse JSON bodies

const users = [];
let currentId = 1;

// POST /users - Create a new user
app.post('/users', (req, res) => {
  const { name, email } = req.body;

  // Basic validation
  if (!name || !email) {
    return res.status(400).json({ error: 'Name and email are required.' });
  }

  const newUser = { id: currentId++, name, email };
  users.push(newUser);

  // Respond with 201 Created and the new user object
  console.log('New user created:', newUser);
  res.status(201).json(newUser);
});

app.listen(3000, () => console.log('Server is running on port 3000'));