A predictable API is easier to use, document, cache and evolve than a collection of ad hoc endpoints.
REST in everyday use means designing an HTTP API around resources identified by URLs, manipulated with standard methods, and represented as JSON.
URLs name things, methods say what to do:
GET /articleslists,POST /articlescreates and returns201with aLocationheader.GET /articles/42reads,PATCHorPUT /articles/42updates,DELETE /articles/42deletes (204).- Sub-resources show relationships:
GET /articles/42/comments. - Plural nouns, lowercase, hyphens:
/order-items, not/getOrderItems.
Actions that don't map cleanly can be modelled as resources (POST /orders/7/cancellation) or, pragmatically, as POST /orders/7/cancel.
Query parameters handle filtering, sorting and pagination: GET /articles?author=ada&sort=-published_at&limit=20.
Consistent errors: use the right status code and a uniform body. RFC 9457 Problem Details (application/problem+json) defines one with type, title, status, detail and room for extra fields, such as per-field validation errors.
Other conventions:
- Pick one naming style for JSON fields (snake_case or camelCase) and stick to it.
- Use ISO 8601 timestamps in UTC.
- Return the created or updated resource in the response so clients don't need another request.
- Describe the API with OpenAPI, which generates docs, client SDKs and tests.
Design from the client's point of view: what will screens and integrations actually need, in how many requests?
Example
POST /v1/articles HTTP/1.1
Content-Type: application/json
{"title": "HTTP caching", "tags": ["web"]}
HTTP/1.1 201 Created
Location: /v1/articles/42
Content-Type: application/json
{"id": 42, "title": "HTTP caching", "tags": ["web"], "created_at": "2026-10-17T09:30:00Z"}
GET /v1/articles?tag=web&sort=-created_at&limit=20 HTTP/1.1
PATCH /v1/articles/42 HTTP/1.1
Content-Type: application/json
{"title": ""}
HTTP/1.1 422 Unprocessable Content
Content-Type: application/problem+json
{"type": "https://api.example.com/errors/validation", "title": "Invalid article",
"status": 422, "errors": [{"field": "title", "detail": "must not be empty"}]}Remember
- Nouns in URLs, verbs as methods
- 201 + Location for creation, 204 for empty success
- Filtering, sorting and paging go in the query string
- Use one error format, e.g. application/problem+json
Watch out for
- Verb-style endpoints like POST /getUser or GET /deleteUser?id=5.