A good API is more than a collection of endpoints. Explore the decisions that make APIs predictable, secure and easier to maintain.
An API succeeds when its consumers can predict what happens, especially when something goes wrong. I begin with the web and mobile teams’ actual workflows: the data each screen needs, how often it changes, and which actions must be safe to retry. Endpoint names come after that contract is understood.
Model resources and responses consistently
Use nouns for resources and the HTTP method for the action: GET to read, POST to create, PATCH to update, DELETE to remove when removal is meaningful. Status codes should distinguish a created resource, a validation error, an unauthorised request and a missing record. A consistent response shape keeps each client from writing special cases for every endpoint.
Validation errors should identify fields and usable messages. Never expose stack traces, table names or internal exception text to a mobile user. Documentation should include examples of success and failure, authentication requirements and the fields clients may rely on.
Design list endpoints for real data
Pagination prevents a once-small collection from becoming a huge response. Define supported filters and sorts explicitly; do not let arbitrary query parameters become database column names. For mobile clients, consider slower connections and avoid making one screen issue many dependent requests when a well-shaped resource can do the work.
Protect the contract
Authentication proves who is calling. Authorisation checks what that identity can do with this specific record. Rate limits protect expensive or sensitive actions but should be chosen for the caller and workflow, not copied blindly. Log enough request context to investigate failures while keeping tokens and private data out of logs.
Actions that may be retried, especially payments or order creation, need an idempotency strategy. A timeout does not tell the client whether the server completed the action. The API should make retries safe and expose a reliable way to check final state.
Evolve without surprising clients
Versioning is useful when a change cannot be introduced compatibly; it is not a substitute for careful change management. Additive fields are usually easier than renaming fields. Deprecate deliberately, communicate timelines and test old clients against new releases.
A good REST API is a dependable agreement between teams. Clear naming, secure access, predictable errors and a sensible evolution path matter more than the number of endpoints.
Walk through one order resource
A customer app might create an order with POST, receive its identifier and status, then read it with GET. A dashboard may list orders with explicit status and date filters, while a manager action changes an order only after authorisation and validation. Both clients should see the same meaning for each status. The response can include useful links or a small summary without exposing database table names.
Consider a mobile retry after a connection drop. If the creation request used an idempotency key, the second attempt can return the original order instead of creating a duplicate. The client can then query the order rather than guessing whether payment or fulfilment started. This behaviour must be documented and tested.
Make errors actionable
A 422 response should tell the client which input failed. A 401 response means authentication is missing or invalid; a 403 response means the caller is known but not allowed. A 404 may also be the right way to avoid revealing a resource that belongs to someone else. Error codes intended for machines should remain stable even if the human-readable message is translated.
Track request identifiers across the API and its dependencies. Support can then investigate a failed action without receiving a screenshot of an internal exception. Avoid logging passwords, access tokens and full payment payloads.
Before a breaking release, test existing mobile versions still in circulation. Web deployments can update quickly; mobile clients may remain installed for months. That difference often determines the API compatibility window.
I design backend APIs around those contracts for web and mobile products.