REST API
REST (Representational State Transfer) is an architectural style for designing APIs, based on working with resources and standard HTTP operations. Each endpoint represents a specific resource and returns a fixed data structure. REST APIs typically use HTTP methods such as GET, POST, PUT, PATCH, and DELETE.
✅ When is it appropriate
REST API is suitable if most of the following apply:
- each operation maps naturally to a resource on the server, such as creating a user or fetching an order
- all clients need roughly the same data from each endpoint without requiring different field selections
- responses must be cacheable by browsers or CDNs to reduce server load
- the API will be consumed by third-party developers who benefit from familiar HTTP conventions
- each endpoint can be called and tested independently using a tool like curl or Postman
- the data model is stable enough that adding a new endpoint is not needed every time the frontend changes
REST maps naturally to how HTTP works. Each endpoint has a unique URL, uses standard HTTP methods such as GET to read and POST to create, and returns a response that the browser or a CDN can cache by its URL. Any developer who knows HTTP can understand a REST API without reading a schema or installing special tooling.
❌ When is it NOT appropriate
REST API may not be ideal if:
- a web app needs only a user's name and avatar while a mobile app needs the full profile, requiring either two endpoints or one endpoint that sends unused data to one client
- displaying a single page requires calling five separate endpoints to assemble the data
- the frontend changes frequently and each change requires a new or modified endpoint on the backend
- several clients with very different data requirements consume the same API, making it impossible to design one response shape that fits all
- the client needs to request only specific fields from a nested resource rather than the full object
When clients need different field combinations, a REST endpoint can only return one fixed response. The web app receives fields it does not use and the mobile app may not receive all the fields it needs, requiring either a second endpoint or custom query parameters that add complexity over time.
👍 Advantages
- each endpoint has a descriptive URL that reveals its purpose, making the API readable without documentation
- GET requests are automatically cached by browsers and CDNs based on the URL, reducing repeated server load
- every major language and framework has libraries, testing tools, and documentation generators built for REST
- each endpoint can be called directly with curl or Postman without any query language or schema setup
- straightforward testing and debugging of individual endpoints
- familiar to any developer who knows HTTP, making public APIs easier to adopt
👎 Disadvantages
- every endpoint returns the same fixed set of fields regardless of what the client actually needs
- a response often includes many fields the client ignores, wasting bandwidth; or it omits fields the client needs, requiring a second request
- assembling data from multiple related resources requires calling several endpoints in sequence
- the frontend cannot request a different field subset without the backend adding or modifying an endpoint
- removing or renaming a field in a response can break existing clients if no versioning strategy is in place
🛠️ Typical use cases
- public APIs available to third-party developers
- CRUD applications where operations map directly to create, read, update, and delete on server resources
- backend for websites or mobile apps where all clients need the same data
- service-to-service communication where each service calls well-defined endpoints of another
- internal services with clear and stable contracts that rarely change
⚠️ Common mistakes (anti-patterns)
- creating a new version of the entire API for every breaking change instead of adding new fields alongside old ones and deprecating them gradually
- naming endpoints after actions rather than resources, such as
/getUserDatainstead of/users/{id}, which breaks the predictable URL pattern that makes REST readable - returning HTTP 200 for every response including errors, forcing clients to parse the response body to detect failures instead of using the status code
- creating one endpoint that returns everything for the page and another that returns just one field, with no consistent granularity principle across the API
- encoding operations in the URL such as
/users/activateinstead of expressing the state change with a HTTP method on the resource
The most common mistake is ignoring HTTP status codes. If every response returns HTTP 200 with an error message in the body, clients cannot tell whether a request succeeded or failed without parsing the response. Monitoring and debugging tools also rely on status codes to detect failures automatically.
💡 How to build on it wisely
Recommended approach:
- Name endpoints after nouns that represent resources rather than verbs that represent actions. Use
GET /orders/{id}instead ofPOST /getOrder. - Return the HTTP status code that matches the outcome: 200 for success, 201 when a resource is created, 400 for invalid input, 401 for missing authentication, 404 when the resource does not exist, and 500 for server errors.
- Add
Cache-Controlheaders to GET responses that return data that does not change per user. This allows browsers and CDNs to serve the response without contacting the server on every request. - Describe the API with an OpenAPI document (a YAML or JSON file that lists every endpoint, its parameters, and response shapes). Tools such as Swagger UI generate interactive documentation from it automatically.
- Add new fields to responses rather than removing or renaming existing ones. When a field must be removed, mark it as deprecated in the documentation and remove it only after confirming no active clients use it.
If the frontend team is adding a new endpoint every time the UI changes, if mobile and web clients regularly receive large amounts of data they do not display, or if a single page view requires four or more sequential API calls, these are concrete signals that a GraphQL API would reduce that friction better than continuing to extend REST.
Related topics
☕ If you found this page helpful, consider supporting my work by buying me a coffee.
Feedback & Sharing
Give us your thoughts on this page, or share it with others who may find it useful.
Share with your network:
Feedback
Found this helpful? Let me know what you think or suggest improvements 👉 Contact me.