What Is a REST API? Resources, HTTP Methods, Statelessness, and Representations Explained
REST is an architectural style for networked systems. It was described by Roy Fielding in his 2000 dissertation and is built around ideas such as resources, a uniform interface, stateless interactions, cacheability, client-server separation, and layered systems.
A REST API commonly uses HTTP, but “REST” is not a programming language, framework, database, or a synonym for “JSON endpoint.”
The easiest way to understand REST is to think in terms of resources and representations.
A resource is the thing the API exposes
A resource is a conceptual object or piece of information in the system.
Examples:
customer
order
invoice
product
comment
A resource is usually identified by a URI:
/customers/c_42
/orders/o_900
/products/p_7
The URI identifies the resource. It does not need to reveal the database table, server path, or storage implementation behind it.
That abstraction is important because the backend can change without changing the public identity of the resource.
A representation is what the client receives
The resource itself and its network representation are different concepts.
A product resource might be represented as JSON:
{
"id": "p_7",
"name": "Mechanical Keyboard",
"price": 4999,
"currency": "INR"
}
Another system could represent a resource as XML, HTML, an image, or another media type.
JSON is extremely common in modern APIs, but REST does not require JSON.
The HTTP Content-Type header tells the recipient how to interpret the representation:
Content-Type: application/json
REST uses a uniform interface
One of REST's central constraints is a uniform interface.
Instead of inventing a completely different network protocol for every resource, clients interact using a consistent set of semantics.
On the web, HTTP methods provide much of that uniform interface.
Typical REST-style APIs use methods such as:
GET
POST
PUT
PATCH
DELETE
The same method semantics apply across many resource types.
That consistency makes generic HTTP infrastructure useful: browsers, proxies, caches, gateways, monitoring tools, and SDKs can understand important parts of the request without knowing every business rule.
GET retrieves a representation
A typical resource read looks like:
GET /orders/o_900
The server might respond:
HTTP/1.1 200 OK
Content-Type: application/json
with:
{
"id": "o_900",
"status": "paid",
"total": 4999
}
RFC 9110 defines GET as a safe method: the client is asking to retrieve a representation rather than requesting a state-changing action.
That makes GET especially suitable for caching and retry behavior.
POST commonly creates or submits work
A client may create an order with:
POST /orders
Content-Type: application/json
Body:
{
"customer_id": "c_42",
"items": [
{ "product_id": "p_7", "quantity": 1 }
]
}
If a new order is created, a useful response is:
HTTP/1.1 201 Created
Location: /orders/o_900
with the canonical created representation.
POST is flexible: it can create a resource or submit data for processing according to the target resource's contract.
It is not inherently idempotent, which matters when clients retry after network failures.
PUT means replacement at a known target
A client can use PUT when it knows the target resource URI and wants to create or replace its state:
PUT /users/u_42/preferences
Content-Type: application/json
Body:
{
"theme": "dark",
"email_notifications": true
}
HTTP defines PUT as idempotent: repeating the same request has the same intended effect as sending it once.
This does not mean every PUT implementation is automatically correct. The server still has to implement replacement semantics consistently.
PATCH applies a partial modification
A PATCH request can represent a partial update:
PATCH /orders/o_900
Content-Type: application/json
Body:
{
"delivery_note": "Leave at reception"
}
PATCH semantics depend on the patch format your API defines.
For interoperable APIs, document whether the endpoint uses JSON Patch, Merge Patch, or a product-specific partial-update structure.
Do not assume every JSON body sent with PATCH has universal semantics.
DELETE requests removal
A resource can be removed with:
DELETE /saved-addresses/a_4
HTTP defines DELETE as idempotent in terms of intended effect.
Deleting the same already-deleted resource again does not need to create a second deletion.
The exact response after repeated deletion can still vary according to the API contract.
Status codes communicate the result
REST-style APIs should use HTTP status codes deliberately.
Common examples:
200 OK
201 Created
202 Accepted
204 No Content
400 Bad Request
401 Unauthorized
403 Forbidden
404 Not Found
409 Conflict
412 Precondition Failed
422 Unprocessable Content
429 Too Many Requests
500 Internal Server Error
503 Service Unavailable
A client should not need to inspect an English message such as "success": false to discover that authentication failed.
HTTP already has a status layer for that purpose.
REST is stateless between requests
The REST stateless constraint means each request contains enough information for the server to understand and process that request without depending on hidden conversational state from a previous request.
For example:
GET /orders/o_900
Authorization: Bearer ...
The request carries the resource target and authentication context it needs.
Stateless does not mean the server has no state.
A REST API can absolutely use:
- databases
- caches
- queues
- object storage
- sessions or tokens
The important idea is that an application server should not require an invisible request-by-request conversation in one specific process to understand the next request.
This makes horizontal scaling and failover much easier.
Client-server separation is another REST constraint
REST separates concerns between client and server.
The client is responsible for presentation and user interaction.
The server owns resources, business rules, authorization, and durable state.
That separation allows:
- frontend and backend teams to evolve independently
- multiple clients to use the same API
- servers to change implementation without rewriting every client
A web app, mobile app, and partner integration can all use the same resource model through different user interfaces.
REST responses can be cacheable
Cacheability is a core REST constraint.
HTTP provides rich caching semantics through headers such as:
Cache-Control: public, max-age=60
ETag: "product-p7-v12"
A cache can reuse a fresh representation without contacting the origin for every request.
A client can also revalidate an older response:
If-None-Match: "product-p7-v12"
If unchanged, the server can respond:
304 Not Modified
This reduces network transfer while keeping freshness controlled.
Personalized or sensitive responses need stricter cache rules; a shared cache should never serve one user's private data to another.
REST supports layered systems
A client does not need to know whether the server it is talking to is the final application process.
A request may pass through:
browser
|
CDN
|
API gateway
|
load balancer
|
application server
This is the layered system constraint.
Intermediaries can provide:
- TLS termination
- caching
- authentication enforcement
- rate limiting
- routing
- compression
- observability
The client interacts with the interface, not every internal network hop.
REST also defines optional code-on-demand
Fielding's REST model includes an optional code-on-demand constraint, where a server may extend client functionality by sending executable code.
The web itself commonly does this through JavaScript delivered to browsers.
Most discussions of REST APIs focus on the other mandatory constraints because code-on-demand is optional and less central to ordinary JSON API design.
“REST API” usually means REST-style HTTP API in practice
Very few production APIs perfectly implement every theoretical aspect of REST.
Many are more accurately described as REST-style or resource-oriented HTTP APIs.
For example, a pragmatic API may expose:
POST /orders/o_900/cancel
instead of forcing every business action into a pure resource-state replacement model.
That is not automatically bad architecture.
The goal is to preserve useful HTTP/resource semantics rather than chase theoretical purity at the expense of a clear product contract.
URLs should identify resources clearly
A resource-oriented API often uses nouns:
/users/u_42
/orders/o_900
/orders/o_900/items
Avoid exposing implementation-specific action endpoints everywhere:
/getUser
/getOrderById
/deleteItemNow
But do not turn “nouns only” into a rigid law.
Some business operations are easier to understand as commands or subresources. Clarity and consistent semantics matter more than superficial URL style.
Query parameters modify a resource request
Parameters are commonly used for:
- filtering
- sorting
- pagination
- field selection
Example:
/orders?status=paid&limit=50&sort=-created_at
This still addresses the orders collection resource; the parameters select a particular representation of that collection.
Put hard limits on page sizes and expensive filters so one request cannot accidentally fetch the entire dataset.
Headers carry request/representation metadata
HTTP headers are useful for cross-cutting metadata such as:
- authentication
- accepted media types
- caching
- conditional requests
- request correlation
- content type
Examples:
Authorization: Bearer ...
Accept: application/json
Content-Type: application/json
If-Match: "order-o900-v3"
Do not hide important business inputs in undocumented custom headers merely because headers are available.
Business fields normally belong in the URI, query parameters, or request body according to the contract.
Accept and Content-Type mean different things
Content-Type describes the representation being sent in the message body.
Content-Type: application/json
Accept tells the server which response media types the client can accept.
Accept: application/json
They often contain the same media type in simple JSON APIs, but they solve opposite directions of content negotiation.
REST does not define authentication
REST is an architectural style, not an authentication protocol.
A REST API can use mechanisms such as:
- secure cookies
- bearer access tokens
- OAuth 2.x / OpenID Connect
- mutual TLS
- API keys for suitable server-to-server use cases
Then every protected resource must still enforce authorization.
A valid token does not mean the caller can access every order, tenant, or admin operation.
HTTPS is the normal production baseline
Protected APIs should use HTTPS.
TLS protects:
- credentials
- cookies
- tokens
- request bodies
- response bodies
REST does not make an insecure HTTP endpoint secure by architectural style.
Transport security and authorization remain explicit application responsibilities.
Safe and idempotent methods help retry logic
HTTP defines useful method properties.
Safe
The client is not requesting a state change.
Examples:
GET
HEAD
Idempotent
Repeating the same request has the same intended effect as performing it once.
Examples include:
GET
PUT
DELETE
This helps clients, gateways, and developers reason about retries after network failures.
POST normally needs application-level idempotency protection when duplicate execution would be harmful.
REST is not the same thing as CRUD
CRUD means:
Create
Read
Update
Delete
Many REST resources do map naturally to CRUD operations, but real APIs also contain domain workflows:
- checkout
- refund
- password reset
- publish article
- approve invoice
REST is about architectural interaction constraints and resource representations, not a rule that every business process must be reduced to four database operations.
REST is not the same thing as HTTP
HTTP is a network application protocol with methods, status codes, headers, caching, content negotiation, and many other semantics.
REST is an architectural style that can use HTTP extremely well.
You can build an HTTP API that is not particularly RESTful—for example, one endpoint that accepts every command through arbitrary RPC names.
Likewise, knowing HTTP deeply is often more useful than memorizing superficial “REST naming rules.”
A simple REST API lifecycle
Imagine an order API.
Create
POST /orders
Server returns:
201 Created
Location: /orders/o_900
Read
GET /orders/o_900
Server returns current representation.
Update a field
PATCH /orders/o_900
Server applies documented partial-update semantics.
Delete/cancel a deletable resource
DELETE /saved-orders/o_900
The same HTTP semantics and resource identity remain understandable across the lifecycle.
When REST-style APIs fit well
REST is a strong choice when:
- resources have clear identities
- ordinary request/response interaction fits the product
- public/third-party integration matters
- browser and generic HTTP tooling are useful
- caching/CDN semantics matter
- request shapes should remain predictable
It is often an excellent default for public web APIs.
When another style may fit better
GraphQL
Useful when clients need flexible field selection across rich connected data.
gRPC
Useful for typed internal RPC contracts, code generation, deadlines, and streaming between controlled services.
WebSocket / realtime protocols
Useful when continuous bidirectional communication is central.
Queues/events
Useful when producers should not wait synchronously for consumers.
A system can use all of these at different boundaries.
There is no requirement that one company choose exactly one communication style forever.
Beginner checklist
When learning REST APIs, remember:
- REST is an architectural style, not a framework.
- APIs expose resources with stable identifiers.
- Clients receive representations of those resources.
- HTTP methods have defined semantics.
- Status codes communicate request outcome.
- Each request should carry the context needed to process it.
- Server-side databases and caches do not violate statelessness.
- Responses can define cache behavior.
- Layered intermediaries such as gateways/CDNs are normal.
- JSON is common but not required by REST.
- Authentication and authorization are separate concerns.
- REST does not require every API to be pure CRUD.
A REST API works well when it lets clients interact with stable resources through predictable HTTP semantics while keeping storage and backend implementation details hidden behind the interface.
References
BUILDING AN AI PRODUCT?
Talk to Lofingo about custom autonomous AI agents, enterprise workflow automation, and scalable software systems.
EXPLORE AI SERVICES →