f in x
REST API Design: naming conventions, status code, and best practices for lasting APIs
> cd .. / HUB_EDITORIALE
Analisi dei dati e metriche

REST API Design: naming conventions, status code, and best practices for lasting APIs

[2026-05-30] Author: Ing. Calogero Bono

Have you ever had to integrate an API where endpoints are named /getUserById and /createNewOrder, while response fields mix snake_case and camelCase? If you work backend, you know this is a recipe for hours of debugging, unreliable documentation, and frustrated developers. We, at Meteora Web, have built dozens of APIs with Laravel and integrated many more—even into ERP systems managing inventory and billing. We've seen that when conventions are weak, the cost isn't just technical: it's financial. A poorly designed API slows development, multiplies errors, and ultimately loses clients. In this guide we share the rules we use every day to design REST APIs that are instantly understandable, maintainable without anxiety, and that scale without tears. No university theory: only naming conventions, status codes, and best practices proven on real projects.

Naming conventions: why the endpoint name is not a cosmetic detail

The resource name and URL structure are the first thing a developer (or client) sees of your API. If they are inconsistent, every request becomes a gamble. We start from a principle: design the API as a collection of resources, not a list of functions. Always use plural names for collection resources: /users instead of /user or /getUsers. Exceptions are singular resources (e.g., /profile for the logged-in user), but even there, prefer /me or an explicit prefix.

Plurality and hierarchy

REST is not about actions (those belong to HTTP methods), but about resources. So GET /users to list, POST /users to create. For relationships, nest consistently: GET /users/123/orders for a user's orders. But avoid excessive depth: more than two levels start to smell. If you have GET /users/123/orders/456/items, maybe it's better to expose GET /items?order_id=456. Pick a convention and apply it everywhere.

Casing in URLs and fields

For URLs, the REST world is split between kebab-case (e.g., /user-addresses) and snake_case. We recommend kebab-case in URLs because it's more readable and case-insensitive by default on many servers. For JSON fields in request and response, the web is divided: snake_case (Python, PHP) vs camelCase (JavaScript). The key is to choose one and stay consistent. We use snake_case in JSON because our backend is PHP/Laravel and the database already uses it. If the client is JavaScript, a middleware can transform it. But switching halfway spells disaster. Example of a consistent response:

{
  "user_id": 42,
  "full_name": "Mario Rossi",
  "created_at": "2025-03-10T14:30:00Z"
}

And never mix verbs and nouns: /users/123 to get details, not /users/getUser?id=123. The HTTP method already says what to do.

Common naming mistakes

  • Putting version in the URL? Yes, always with /v1/ at the start. Don't mix versions at the resource level.
  • Never use actions like /deleteUser – use DELETE /users/123.
  • Avoid underscores in resource names: /user_addresses is okay, but kebab-case /user-addresses is better.
  • Never change a resource name after release. If you must, deprecate with a Warning header or a new version.

Status codes: letting HTTP speak for itself

Status codes are the fastest way to communicate the result of a request. Using them well saves hours of log analysis and debugging. We often see APIs that always return 200 with an error: true field in the body. That's a terrible habit: the client must parse the JSON to know what happened. Instead, let the protocol do the talking.

Codes you must know and always use

  • 200 OK – successful request (GET, PUT, PATCH).
  • 201 Created – resource successfully created (POST). Include the created resource in the body and a Location header with its URL.
  • 204 No Content – operation with no response body (DELETE, or PUT with no need to return data).
  • 400 Bad Request – client-side error (malformed JSON, missing parameters).
  • 401 Unauthorized – missing or invalid authentication.
  • 403 Forbidden – authenticated but not authorized.
  • 404 Not Found – resource does not exist.
  • 409 Conflict – conflict with current state (e.g., duplicate, outdated version).
  • 422 Unprocessable Entity – validation failure (widely used with frameworks like Laravel).
  • 429 Too Many Requests – rate limit exceeded.
  • 500 Internal Server Error – generic server error.
  • 503 Service Unavailable – server temporarily unavailable (maintenance, overload).

Uniform error responses

Don't just return a code. Always include a consistent body with error details. The structure we use:

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "The email field is required.",
    "details": {
      "email": ["The email is required."]
    }
  }
}

Include an internal code (more specific than HTTP), a developer-friendly message, and additional details. Never expose stack traces in production. Never send error messages that reveal internal details (database type, software version).

Best practices for a design that lasts

Version from day one

No API stays unchanged forever. Put the version in the URL (/v1/) or in the header Accept: application/vnd.api.v1+json. We prefer the URL because it's explicit and works with any client. Even if it seems stable today, a new requirement can turn everything around in six months. With versioning, you can evolve without breaking existing clients.

Pagination, filtering, and sorting

Every list endpoint must be paginated. Use parameters page and per_page or offset/limit. Include metadata in the response: total, current_page, last_page. For filters, use dedicated parameters: ?status=active or ?created_after=2025-01-01. For sorting, ?sort=created_at,-name (ascending default, - for descending).

Idempotency and security

GET, PUT, DELETE must be idempotent: calling them multiple times yields the same result. POST is not. Use idempotency tokens (header Idempotency-Key) for sensitive operations (e.g., payments) to avoid duplicates. And please, always use HTTPS. An API without HTTPS is a security flaw that exposes credentials and sensitive data. We see this often: clients using HTTP in production. Fix it now.

Documentation with OpenAPI

An undocumented API is an API that doesn't exist. Write the OpenAPI specification (formerly Swagger) starting from the design – before writing any code. We do this with OpenAPI 3.1. It forces you to define every endpoint, parameter, schema. Moreover, you can generate client SDKs and automatic validation.

Rate limiting and caching

Protect your API from overload: return 429 Too Many Requests and include a Retry-After header. For caching, use Cache-Control and ETag headers for GET responses that don't change often. Avoid caching sensitive data.

In short: what to do now

  1. Review your resource names: use English plurals, kebab-case in URLs, snake_case in JSON. Rename anything inconsistent (mind backward compatibility).
  2. Standardize status codes and error responses: each endpoint must return the correct HTTP code and a uniform body. Never use 200 for errors.
  3. Add versioning from your next deployment: prepend /v1/ to all endpoints. Existing clients can keep hitting the unversioned API until deprecation.
  4. Document with OpenAPI: create a YAML/JSON file describing the entire API. Free tools like Swagger Editor help. It will cost you a few hours but save dozens of support hours.
  5. Audit each endpoint for security (HTTPS, rate limiting, idempotency of modifying operations). Don't wait for an incident.

We, at Meteora Web, started applying these practices years ago when we built APIs for accounting and inventory systems. Believe us: clean design is not just aesthetics – it's an economic choice. Fewer bugs, faster onboarding, happier clients. And if you'd like to discuss how to structure your API, talk to us.

Sponsored Protocol

Ing. Calogero Bono

> AUTHOR_EXTRACTED

Ing. Calogero Bono

Co-founder di Meteora Web. Ingegnere informatico, sviluppo ecosistemi digitali ad alte prestazioni. AI, automazione, SEO tecnica e infrastrutture web. Scrivo di tecnologia per rendere complesso… semplice.

[ Read Full Dossier ]

Hai bisogno di applicare questa strategia?

Esegui il protocollo di contatto per iniziare un progetto con noi.

> INIZIA_PROGETTO

Sponsored

> MW_JOURNAL

> READ_ALL()