REST is the dominant style for designing HTTP APIs. This lesson covers REST's core principles and how they map onto Express routes, HTTP verbs, and status codes.
What Makes an API RESTful?
REST (Representational State Transfer) organizes an API around resources, nouns like users, orders, products, each identified by a URL, and manipulated using standard HTTP verbs: GET to read, POST to create, PUT/PATCH to update, DELETE to remove.
A well-designed REST API is predictable: the same conventions (plural resource names, verb-based actions, consistent status codes) apply across every endpoint, which is what makes REST APIs easy for other developers to learn quickly.
Notice the pattern: /products (the collection) for listing and creating, /products/:id (a single resource) for reading, updating, or deleting one item.
REST Resource Conventions
GET /products -> list all products
GET /products/:id -> get one product
POST /products -> create a product
PUT /products/:id -> replace a product
PATCH /products/:id -> partially update a product
DELETE /products/:id -> delete a product
Resource names are plural nouns (/products, not /product or /getProducts).
The HTTP verb, not the URL, expresses the action, avoid verbs in the path itself.
PUT conventionally replaces an entire resource; PATCH updates only the given fields.
Nested resources use nested paths, e.g. /orders/:orderId/items.
REST API Cheatsheet
Standard conventions used across most well-designed REST APIs.
Action
Method + Path
Success Status
List resources
GET /products
200
Get one resource
GET /products/:id
200
Create a resource
POST /products
201
Replace a resource
PUT /products/:id
200
Partially update
PATCH /products/:id
200
Delete a resource
DELETE /products/:id
204
REST APIs Should Be Stateless
Each request to a REST API should carry all the information the server needs to process it (an auth token, required parameters), without relying on server-side session state left over from a previous request. This makes REST APIs easy to scale horizontally, any server instance can handle any request.
Structuring an API Into Layers
As an API grows, separating concerns into layers, routes (HTTP-specific), controllers (translate requests to business logic calls), and services (the actual business logic), keeps the codebase testable and easy to navigate.
// routes/products.js -> defines the URLs and HTTP verbs
// controllers/productsController.js -> reads req, calls the service, sends res
// services/productService.js -> actual business logic, no knowledge of req/res
This separation means your business logic (in services) can be unit tested without spinning up an HTTP server at all.
Common Mistakes
Putting verbs in URLs, like /getProducts or /createProduct, instead of letting the HTTP method express the action.
Returning 200 OK for every response regardless of what actually happened, ignoring more precise status codes.
Mixing business logic directly into route handlers instead of separating it into a service layer.
Designing an API that depends on server-side session state between otherwise-stateless requests.
Key Takeaways
REST organizes APIs around resources (nouns), manipulated via standard HTTP verbs.
Consistent conventions (plural names, correct status codes) make an API predictable to use.
REST APIs should be stateless, each request carries everything the server needs.
Separating routes, controllers, and services keeps larger APIs maintainable and testable.
Pro Tip
Before writing a single route, sketch your API's resources and their URLs on paper first (/users, /users/:id/orders, ...). Getting the resource hierarchy right up front avoids painful, breaking URL changes later.
You now understand REST API design principles. Next, build a complete CRUD API implementing every operation on a resource.