Skip to content

Grokem · https://www.grokem.com/programming/apis-integrations/rest/rest-api-design-checklist

RESTBest practices

A REST API design checklist

Resources, methods, status codes, errors, pagination, versioning and security: the decisions that make an HTTP API predictable for the people who build on it.

Grokem Editorial

Editorial desk

Published
  • 3 min read

An API is a promise to people you may never meet: do this, and you will get that. The quality of the promise decides how easily they can build on it. This checklist is arranged around the decisions that matter most, and the reasons behind them.

Why predictability is the goal

Developers learn your API once and then guess the rest. If listing orders is GET /orders, they will try GET /customers for customers, and it should work. Every surprise (a verb in a path, a different error shape, a date in another format) costs someone an afternoon, so consistency is worth more than any single clever design.

The groups of decisions

Resources and methods. Name the things, not the actions, and use HTTP's methods for the actions. This lets standard tools (caches, proxies, clients) behave correctly, because they understand that a GET is safe to repeat and a POST is not.

Status codes and errors. A client decides what to do from the status code, then reads the body to find out why. Use the specific code (a 404 is not a 400), and return errors in one consistent shape that code can parse, not a sentence meant for a person.

Lists. Unbounded lists are an outage waiting to happen. Paginate everything, document the limits, and give filters and sorting the same names everywhere.

Changes over time. Clients cannot upgrade the moment you do. Add fields freely, never change the meaning of an existing one, and announce removals long before they happen.

Safety. Authenticate every non-public endpoint, check permissions per object (the classic failure is letting any signed-in user read /orders/42 by changing the number), validate input, rate-limit, and never leak internals in an error.

Documentation. An API without accurate documentation is guesswork. An OpenAPI description can generate reference pages, client libraries and tests.

An example of consistent errors

A response that tells the client everything it needs, in a shape it can always rely on, following RFC 9457:

json
{
  "type": "https://example.com/problems/validation-error",
  "title": "Your request is not valid",
  "status": 422,
  "detail": "One or more fields failed validation.",
  "errors": [
    { "field": "email", "message": "must be a valid e-mail address" },
    { "field": "quantity", "message": "must be at least 1" }
  ],
  "request_id": "7f3c2a9e"
}

The status repeats the HTTP code for clients that only see the body, errors lets a form highlight the right fields, and request_id lets support find the matching log entry.

Using the checklist

Run it as a review on a design before you build, since changing a published API is far more expensive than changing a sketch. Then use it again each time you add an endpoint, so the style stays consistent as the API grows. Where you decide to break a rule, write down why, so the next person does not have to rediscover it.

Checklist

  • Name resources with plural nouns and let the HTTP method be the verb: GET /orders, POST /orders, GET /orders/42. Avoid verbs in paths such as /getOrder.
  • Use methods for what they mean. GET reads and has no side effects, POST creates or triggers, PUT replaces, PATCH changes part, DELETE removes. GET, PUT and DELETE should be safe to repeat.
  • Return accurate status codes: 201 with a Location header for a created resource, 204 for success with no body, 400 for a bad request, 401 and 403 for authentication and permission, 404 for not found, 409 for a conflict, 422 for valid syntax with invalid content, 429 when rate limited.
  • Return errors in one consistent, machine-readable shape. The Problem Details format (RFC 9457) gives a standard: type, title, status, detail and an optional list of field errors.
  • Paginate every list, and prefer cursors for data that changes. Document the default and maximum page size, and return what the client needs to ask for the next page.
  • Support filtering, sorting and field selection through query parameters with consistent names, and validate them. Reject unknown parameters clearly instead of ignoring them.
  • Use one format for dates and times (ISO 8601 / RFC 3339 in UTC, for example 2025-03-01T09:30:00Z), one naming style for fields, and one way to represent money (an integer in the smallest unit plus a currency code).
  • Make unsafe operations safe to retry: accept an idempotency key for POST requests that create things, so a client that times out can try again without duplicates.
  • Version deliberately. Choose a scheme (a path prefix such as /v1 or a header), add fields without breaking old clients, and announce removals with a deprecation period.
  • Secure it: HTTPS only, authentication on every non-public endpoint, authorisation checks on every object (not only on the route), input validation and limits on request size.
  • Rate-limit, and tell clients where they stand with headers and a Retry-After on 429 responses.
  • Support caching where it helps: ETag and If-None-Match let clients skip downloading what has not changed; Cache-Control says how long a response may be reused.
  • Describe the API with an OpenAPI document, keep it in step with the code, and publish examples of real requests and responses.
  • Never expose internals in errors: no stack traces, SQL or file paths. Log them on the server with a request id, and return that id to the client.

Frequently asked questions

Is a REST API the same as any HTTP API?

Not strictly. REST is a set of constraints (resources, uniform interface, statelessness and others). Most 'REST' APIs follow some of them, and the practical goal is simply a predictable, well-behaved HTTP API.

PUT or PATCH for updates?

PUT replaces the whole resource with the body you send, so missing fields are removed. PATCH changes only the fields you send. PATCH is more convenient for clients, PUT is simpler to reason about.

References

From Grokem: https://www.grokem.com/programming/apis-integrations/rest/rest-api-design-checklist

How did this strike you?

Be the first to react – it is anonymous.

Comments

No comments yet. Share what worked for you, or ask a question.

Keep going

All in topic

Choose what we may use. You can change this at any time with “Privacy choices” at the foot of every page. Details are in the Cookie policy and the Privacy policy.

Strictly necessary

Remembers your theme, the lessons you marked as done and this choice. It stays on your device, tracks nothing and cannot be switched off.

Always on
What exactly is collected, and why

Grokem’s own counts

Collects
The pages you open and how long you stay, how far you scroll, where you came from, your device type, browser, screen size, language and time zone. Your IP address is turned into a code that changes every day; it is never stored as it is.
Why
To see how long lessons are read and where readers leave. Not shared with anyone.
Stored
A random visitor ID, a visit ID and the time of your last page view in your browser’s storage (gr_vid, gr_sid, gr_last). No name or email is attached.