← All postsEngineering

REST API: the conventions that make one predictable

REST is a set of constraints, not a specification, which is why every API claiming to be RESTful is different. The conventions worth following are the ones that let a developer guess correctly.

EngineeringR

A REST API exposes resources over HTTP, using the methods and status codes the protocol already defines. The original constraints are architectural and stricter than common usage; in practice, when somebody says REST API they mean an HTTP interface with resource URLs, JSON bodies, and verbs that mean what they say.

That looseness is exactly why conventions matter. The value of a predictable API is that a developer who has read half the documentation can guess the rest correctly — and every deviation from convention costs somebody an hour of their life.

The conventions that carry most of the value

  • Nouns for resources, plural, hierarchical: /invoices, /invoices/42, /invoices/42/lines. Not /getInvoice.
  • Methods that mean what they mean. GET never changes anything, PUT replaces, PATCH updates part, DELETE removes. A GET with side effects will be cached and repeated by something you do not control.
  • Status codes from the standard set: 200, 201 with a Location header, 204 for empty success, 400 for bad input, 401 unauthenticated, 403 unauthorised, 404 missing, 409 conflict, 422 unprocessable, 429 rate limited, 500 for your fault. Returning 200 with an error inside the body breaks every generic client.
  • One error shape everywhere, with a machine-readable code and a human-readable message. Clients switch on the code and log the message.
  • Consistent naming and date formats — pick snake or camel case and never mix, and use ISO 8601 with a timezone for every timestamp.
  • Pagination on every collection, from the first version. Retrofitting it is a breaking change, and unbounded lists are how APIs fall over.

Idempotency is the property that matters most in practice and gets the least attention. A network failure leaves a client genuinely unable to tell whether a write succeeded, so it will retry — and a POST that creates a second invoice on retry is a real incident. Accept an idempotency key on every write that creates something, and return the original result when the same key comes back.

Things that hurt later

  1. No versioning. Decide before the first customer: a version in the path is crude and completely predictable, which at small scale beats elegance.
  2. Returning different shapes for the same resource in different endpoints. Clients build one model; give them one shape.
  3. Deep nesting. Beyond two levels the URLs become unguessable and the queries slow. Use query parameters instead.
  4. Leaking database structure. Column names and internal ids in the API mean schema changes become breaking changes.
  5. Silent truncation, silent coercion, silently ignored unknown fields. Reject clearly instead — the debugging time saved is enormous.

REST, GraphQL, RPC

REST suits resources with predictable shapes and many consumers, which is most business APIs. GraphQL suits clients that need widely varying slices of a large graph and are prepared to own the query complexity — it moves work from the server to the client and to the caching layer, which is a trade rather than an upgrade. RPC styles suit actions that are genuinely not resources: a verb like recalculate does not become clearer as a noun. Choosing REST because it is conventional is a perfectly good reason; choosing GraphQL because it is newer is not.

Where Ettex fits

Ettex API follows the conventions above, and the event side is covered in webhook, with the practicalities of building against any API in api integration.

One limitation stated plainly: this article describes conventions rather than our endpoint list. For what exists, at what version, and under which limits, read the current API documentation rather than inferring it from a blog post — including this one.

Frequently asked

What makes an API RESTful?

Resources addressed by URL, HTTP methods used for their defined meanings, stateless requests, and standard status codes. Strict REST is stricter than common usage, which is why conventions matter more than the label.

Should the version go in the URL or a header?

In the URL for most APIs. It is crude and completely predictable, it survives being pasted into a browser, and predictability is worth more than elegance at small scale.

What status code should an API return for a validation error?

400 for malformed input, 422 for well-formed input that fails business rules. Never 200 with an error in the body — that breaks generic clients and monitoring.

Why does an API need idempotency keys?

Because a network failure leaves the client unsure whether the write happened, so it retries. Without a key, the retry creates a duplicate record.

SL
Written by Sofia L.

Part of the Ettex team — writing about product, engineering and the future of work.

More posts
Get the best of the Ettex blogProduct news, guides and tips — straight to your inbox, no spam.