A REST API is an application programming interface that follows the Representational State Transfer architectural style: it exposes data as resources identified by URLs and lets clients read and change them with standard HTTP methods such as GET, POST, PUT, PATCH and DELETE. Each request is stateless and carries everything the server needs to process it.
Roy Fielding defined REST in his doctoral dissertation in 2000 as a description of the architecture of the web itself. Among APIs in programming, REST over HTTP with JSON payloads has become the most common style for public web services, mobile back ends and communication between internal services, competing with GraphQL, gRPC and JSON-RPC for specific use cases.
The architectural constraints behind REST
REST is not a protocol or a standard but a set of architectural constraints. An API earns the label by respecting them, and each constraint buys a specific system property such as scalability or independent evolution of client and server.
| Constraint | What it requires | Property it provides |
|---|---|---|
| Client-server | Separate user interface from data storage | Independent evolution of both sides |
| Statelessness | No client session stored on the server between requests | Horizontal scaling, simple load balancing |
| Cacheability | Responses label themselves as cacheable or not | Fewer requests, lower latency |
| Uniform interface | Same methods and conventions for every resource | Simplicity and visibility to intermediaries |
| Layered system | Client cannot tell if it talks to a proxy or origin | Gateways, caches and load balancers |
| Code on demand | Server may send executable code | Optional extension of clients |
The uniform interface is the defining constraint. It includes identifying resources by URI, manipulating them through representations such as JSON documents, using self-descriptive messages, and hypermedia as the engine of application state (HATEOAS), in which responses contain links that tell the client which actions are possible next.
How HTTP methods map to operations
A REST API models its domain as nouns, not verbs. Instead of an endpoint called /getOrder, it exposes a collection /orders and individual resources such as /orders/42, and the HTTP method states the action. Two method properties defined by the HTTP specification matter for reliability: a safe method does not change server state, and an idempotent method has the same effect whether it is sent once or several times.
| Method | Typical use | Safe | Idempotent |
|---|---|---|---|
| GET | Read a resource or a collection | Yes | Yes |
| POST | Create a resource in a collection or trigger processing | No | No |
| PUT | Replace a resource completely | No | Yes |
| PATCH | Modify part of a resource | No | Not guaranteed |
| DELETE | Remove a resource | No | Yes |
| HEAD | Read headers only, without a body | Yes | Yes |
Idempotence decides what a client may retry safely after a timeout. Repeating a PUT is harmless, but repeating a POST can create a duplicate order, which is why payment APIs often accept an idempotency key header that lets the server recognize and ignore a repeated request.
Status codes and response design
A well-designed REST API communicates results through HTTP status codes first and through the response body second. Clients, proxies and monitoring tools all understand the status code without parsing the payload.
| Code | Meaning | Typical situation |
|---|---|---|
| 200 OK | Request succeeded | Successful read or update |
| 201 Created | New resource created | Successful POST, with a Location header |
| 204 No Content | Success with an empty body | Successful DELETE |
| 400 Bad Request | Malformed or invalid input | Missing required field |
| 401 Unauthorized | Authentication missing or invalid | Expired access token |
| 403 Forbidden | Authenticated but not permitted | User lacks the required role |
| 404 Not Found | Resource does not exist | Unknown order ID |
| 409 Conflict | State conflict | Concurrent edit, duplicate key |
| 429 Too Many Requests | Rate limit exceeded | Client sends too fast |
| 500 Internal Server Error | Unexpected server failure | Unhandled exception |
Error bodies should follow a consistent machine-readable format. Many teams adopt the problem details format standardized in RFC 9457, which defines fields such as type, title, status and detail. Contracts are commonly documented with the OpenAPI specification, which also drives code generation and automated contract tests.
REST compared with other API styles
REST is a strong default, but not the best fit for every workload. The comparison below shows where it stands against the other styles in the same field.
| Aspect | REST | GraphQL | gRPC |
|---|---|---|---|
| Data model | Resources at many URLs | One schema at one endpoint | Services with typed methods |
| Typical payload | JSON | JSON | Protocol Buffers, binary |
| Response shape | Fixed by the server | Chosen by the client query | Fixed by the message type |
| HTTP caching | Native and simple | Harder, mostly POST requests | Not used directly |
| Best fit | Public and general web APIs | Varied client data needs | Fast internal service calls |
The main weaknesses of REST are over-fetching and under-fetching: a fixed response may contain more fields than a screen needs, or too few, forcing several round trips. GraphQL addresses this directly, while gRPC wins on latency and payload size between internal services.
Maturity levels and common design mistakes
Many APIs called RESTful implement only part of the style. The Richardson maturity model describes four levels: level 0 sends everything to one endpoint, level 1 introduces resources, level 2 adds proper HTTP methods and status codes, and level 3 adds hypermedia controls. Most production APIs stop at level 2, which is pragmatic but technically short of full REST as Fielding defined it.
- Verbs in URLs such as
/createUserduplicate what the HTTP method already expresses. - Returning 200 for errors with an error flag in the body hides failures from clients, caches and monitoring.
- Storing session state on the server breaks statelessness and complicates scaling.
- Unbounded collections without pagination cause slow responses; use limit and cursor parameters.
- Breaking changes without versioning break existing clients; version through the path or a header.
Stripped to the essentials
A REST API works like a well-organized library counter. Every item has a fixed shelf address, and there are only a few standard requests: show me this item, add a new one, replace it, or remove it. Because everyone uses the same short list of requests, any visitor can work with any shelf without learning special rules.
Each visit is complete on its own: the counter does not need to remember previous visits, so many clerks can serve many visitors at the same time.
Where it is applied
A food delivery company exposes a REST API to its mobile apps. The app lists nearby restaurants with GET /restaurants?lat=48.15&lon=17.11&limit=20, places an order with POST /orders and receives 201 Created together with the new order URL, then polls GET /orders/9812 to show delivery progress.
Because the API is stateless, the company runs it on twelve identical servers behind a load balancer and adds more during the dinner peak. Restaurant menus change rarely, so GET responses carry a five-minute cache header and are served by a content delivery network, which removes most menu requests from the application servers. A weak mobile connection that times out on order submission is no problem either: the app retries with the same idempotency key, and the server returns the original order instead of creating a duplicate.