REST
REST
Learn how to design resource-oriented APIs using HTTP methods, representations, status codes, stateless requests, caching, validation, idempotency and consistent service contracts.
Introduction
An Application Programming Interface, commonly abbreviated as API, defines how software components communicate. A well-designed API provides a stable contract that allows clients and services to evolve independently.
REST stands for Representational State Transfer. REST is an architectural style for distributed systems. A REST-oriented API models important concepts as resources, identifies those resources through URIs and uses standard HTTP semantics to operate on their representations.
REST-oriented API design commonly involves:
- Resource identification
- Representations
- Standard HTTP methods
- HTTP status codes
- Stateless requests
- Cache controls
- Uniform interaction patterns
- Validation and error contracts
- Authentication and authorization
- Idempotency and retry behaviour
Core idea: A REST API should expose meaningful resources and use HTTP semantics consistently. Clients should understand an operation from its method, resource URI, fields, representation and documented response contract.
In your System Design curriculum, REST is Topic 4.1 under API Design & Service Contracts. This module also covers RPC and gRPC, GraphQL, resource modelling, pagination, versioning, idempotency, authentication versus authorization and rate-limit semantics.
Prerequisites
| # | Prerequisite | Why It Is Needed |
|---|---|---|
| 1 | HTTP methods and status codes | REST APIs use HTTP semantics to express operations and outcomes. |
| 2 | HTTP fields and representations | Clients and servers exchange metadata and resource representations. |
| 3 | JSON | JSON is commonly used to represent API resources and errors. |
| 4 | TLS and HTTPS | API credentials and application data require protected transport. |
| 5 | Authentication and authorization basics | Identifying a caller and permitting an operation are separate responsibilities. |
| 6 | Database fundamentals | Many API resources are backed by persistent application state. |
What Is an API Contract?
An API contract defines the observable behaviour on which clients can rely.
A complete contract can define:
- Resource URIs
- Supported methods
- Request fields
- Request body schemas
- Response schemas
- Status codes
- Error formats
- Authentication requirements
- Authorization rules
- Validation constraints
- Pagination behaviour
- Retry and idempotency behaviour
- Rate-limit behaviour
- Compatibility guarantees
Resource-oriented Design
A resource is a concept or entity exposed through the API. Examples include customers, orders, products, invoices and shipments.
Resource-oriented URIs commonly use nouns:
/customers
/customers/42
/customers/42/orders
/orders/9001
/products
/products/ABC-100
POST /createCustomer
GET /getCustomerById?id=42
POST /deleteCustomer?id=42
POST /customers
GET /customers/42
DELETE /customers/42
The HTTP method expresses the intended operation, while the URI identifies the target resource.
Collection and Item Resources
| Resource | Example URI | Purpose |
|---|---|---|
| Customer collection | /customers |
Represents the customer collection |
| Customer item | /customers/42 |
Represents one customer |
| Order collection | /orders |
Represents the order collection |
| Order item | /orders/9001 |
Represents one order |
| Customer orders | /customers/42/orders |
Represents orders associated with one customer |
HTTP Methods in REST
| Method | Common Resource Operation | Safe | Idempotent |
|---|---|---|---|
| GET | Retrieve a representation | Yes | Yes |
| HEAD | Retrieve response metadata without response content | Yes | Yes |
| POST | Submit data for processing or create a subordinate resource | No | Not inherently |
| PUT | Create or replace the state of the target resource | No | Yes |
| PATCH | Apply a partial modification | No | Depends on the patch operation |
| DELETE | Remove the target resource association | No | Yes |
| OPTIONS | Describe communication options | Yes | Yes |
GET
GET requests retrieve a representation of a resource. A GET request should not request a state-changing operation.
GET /customers/42 HTTP/1.1
Host: api.example.com
Accept: application/json
Authorization: Bearer ACCESS_TOKEN
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: private, max-age=60
ETag: "customer-42-v7"
{
"id": 42,
"name": "Example Customer",
"status": "active"
}
Avoid State Changes through GET
GET /orders/9001/cancel
POST /orders/9001/cancellation
Browsers, caches, crawlers and monitoring systems can issue GET requests without expecting business state to change.
POST
POST submits content for processing according to the target resource's semantics. It is commonly used to create a resource within a collection.
POST /customers HTTP/1.1
Host: api.example.com
Content-Type: application/json
Accept: application/json
Idempotency-Key: client-generated-key
{
"name": "Example Customer",
"email": "customer@example.com"
}
HTTP/1.1 201 Created
Location: /customers/42
Content-Type: application/json
{
"id": 42,
"name": "Example Customer",
"email": "customer@example.com",
"status": "active"
}
A successful creation response can use 201 Created and identify
the created resource through the Location response field.
PUT
PUT creates or replaces the state of the target resource using the supplied representation.
PUT /customers/42 HTTP/1.1
Host: api.example.com
Content-Type: application/json
If-Match: "customer-42-v7"
{
"name": "Updated Customer",
"email": "updated@example.com",
"status": "active"
}
The contract should explicitly define whether omitted fields are removed, reset or rejected.
PATCH
PATCH applies a partial modification according to the selected patch media type and API contract.
PATCH /customers/42 HTTP/1.1
Host: api.example.com
Content-Type: application/merge-patch+json
If-Match: "customer-42-v7"
{
"status": "inactive"
}
A patch should clearly distinguish between:
- A field that is not supplied
- A field explicitly set to null
- A field being removed
- A field retaining its current value
DELETE
DELETE /customers/42 HTTP/1.1
Host: api.example.com
Authorization: Bearer ACCESS_TOKEN
HTTP/1.1 204 No Content
DELETE expresses removal of the target resource association. The application can implement physical deletion, logical deletion, archival or another documented lifecycle transition.
Contract rule: A client should not need to guess whether DELETE performs immediate physical deletion, soft deletion or an asynchronous deletion workflow. Document the observable behaviour.
Safe and Idempotent Methods
A safe method is intended for information retrieval and should not request a change to application state.
An idempotent method has the same intended effect when an identical request is applied once or several times.
PUT /customers/42
Apply once:
Customer state becomes version X.
Apply the same replacement again:
Customer state remains version X.
POST /orders
Apply once:
Order 100 is created.
Apply again without idempotency protection:
Order 101 might also be created.
Idempotency describes the intended effect, not whether every response, timestamp, log entry or generated metadata is identical.
Resource Representations
A resource is a conceptual object. A representation is the transferred form describing some state of that resource.
{
"id": 9001,
"status": "confirmed",
"currency": "USD",
"total": 149.50,
"customer": {
"id": 42,
"name": "Example Customer"
},
"links": {
"self": "/orders/9001",
"customer": "/customers/42"
}
}
A representation should use stable field names, documented data types, defined nullability and consistent formats.
Content Types
The Content-Type field describes the media type of request or
response content.
Content-Type: application/json
The Accept request field communicates media types acceptable
to the client.
Accept: application/json
An API should reject unsupported request content types with a documented result rather than attempting to guess the payload format.
REST Status Codes
| Status | Typical Meaning in an API |
|---|---|
200 OK |
The operation succeeded and a response representation is returned |
201 Created |
A new resource was created |
202 Accepted |
The request was accepted for asynchronous processing |
204 No Content |
The operation succeeded without response content |
304 Not Modified |
A conditional retrieval can reuse a cached representation |
400 Bad Request |
The request is malformed or fails general request requirements |
401 Unauthorized |
Authentication credentials are missing or unacceptable |
403 Forbidden |
The request is understood but not permitted |
404 Not Found |
The target resource was not found or is intentionally not disclosed |
405 Method Not Allowed |
The target resource does not support the method |
409 Conflict |
The request conflicts with current resource state |
412 Precondition Failed |
A request precondition such as If-Match was false |
415 Unsupported Media Type |
The request content type is unsupported |
422 Unprocessable Content |
The content syntax is understood but semantic validation fails |
429 Too Many Requests |
The caller exceeded an applicable rate policy |
500 Internal Server Error |
An unexpected server failure occurred |
503 Service Unavailable |
The service is temporarily unable to process the request |
Error Response Contract
APIs should use a consistent machine-readable error representation.
{
"type": "https://api.example.com/problems/validation-error",
"title": "Request validation failed",
"status": 422,
"detail": "One or more request fields are invalid.",
"instance": "/customers/requests/req-8f21",
"errors": [
{
"field": "email",
"code": "invalid_format",
"message": "Enter a valid email address."
}
],
"traceId": "8f21c9a7"
}
A useful error contract can include:
- A stable machine-readable error type or code
- A human-readable title
- The HTTP status
- A safe explanation
- Field-level validation errors
- A correlation or trace identifier
{
"error": "SQLSTATE[42S02\]: Table 'prod.users' not found",
"query": "SELECT * FROM users WHERE email = ...",
"file": "/var/www/app/UserRepository.php",
"line": 87
}
{
"type": "internal-error",
"title": "The request could not be completed",
"status": 500,
"traceId": "8f21c9a7"
}
Detailed diagnostic information belongs in protected server logs, linked through an appropriate correlation identifier.
Request Validation
Validation should occur before applying a business operation.
Validation can include:
- Required fields
- Data types
- String length
- Numeric range
- Enumeration values
- Date and time formats
- Identifier format
- Cross-field relationships
- Current business state
- Maximum request size
Authentication vs Authorization
| Concern | Question |
|---|---|
| Authentication | Who or what is calling the API? |
| Authorization | Is the authenticated caller allowed to perform this operation on this resource? |
Request arrives
|
v
Validate credential
|
v
Establish caller identity
|
v
Load target resource
|
v
Evaluate operation-level authorization
|
+--> Allowed: continue
|
+--> Denied: reject
Authentication success does not grant access to every resource. Every protected operation requires an authorization decision.
Prevent Object-level Authorization Defects
GET /accounts/9002
The API returns account 9002
because the caller is authenticated.
1. Authenticate the caller.
2. Load account 9002.
3. Evaluate whether the caller may view account 9002.
4. Return the representation only when authorized.
Stateless Requests
REST's stateless constraint requires each request to contain the information necessary for the server to understand and process it.
GET /orders/9001 HTTP/1.1
Host: api.example.com
Authorization: Bearer ACCESS_TOKEN
Accept: application/json
X-Correlation-ID: request-1042
Statelessness does not mean the application has no persistent state. Orders, users and authorization data can exist in databases. It means the server does not depend on undocumented conversational context from an earlier request.
REST and Caching
HTTP caching can reduce latency, server load and repeated data transfer.
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: private, max-age=60
ETag: "customer-42-v7"
A cache policy should define:
- Whether the response can be cached
- Whether a shared cache can store it
- How long the response remains fresh
- How stale responses are revalidated
- Which request fields affect the representation
- Whether authenticated or personal data can be cached
Conditional Requests with ETags
Conditional GET
GET /customers/42 HTTP/1.1
Host: api.example.com
If-None-Match: "customer-42-v7"
HTTP/1.1 304 Not Modified
ETag: "customer-42-v7"
The client can reuse its cached representation when the validator still matches.
Optimistic Update
PATCH /customers/42 HTTP/1.1
Host: api.example.com
Content-Type: application/merge-patch+json
If-Match: "customer-42-v7"
{
"status": "inactive"
}
If the resource changed after the client retrieved version 7, the server can reject the update because the precondition is false.
Idempotency Keys
POST is not inherently idempotent. A client can use an idempotency key when safely retrying a supported operation after an uncertain response.
POST /payments HTTP/1.1
Host: api.example.com
Content-Type: application/json
Idempotency-Key: b610fb48-a5ac-4d54-93d2-a1f6e5cc6844
{
"orderId": 9001,
"amount": 149.50,
"currency": "USD"
}
First request:
Validate idempotency key
Process payment
Store operation result
Return response
Retry with same key and same request:
Find stored result
Do not create another payment
Return the original outcome
Same key with different request:
Reject as an idempotency-key conflict
Synchronous vs Asynchronous Operations
A short operation can return its final result synchronously. A long-running operation can return an operation resource.
POST /reports HTTP/1.1
Host: api.example.com
Content-Type: application/json
{
"reportType": "annual-summary",
"year": 2026
}
HTTP/1.1 202 Accepted
Location: /operations/op-701
Content-Type: application/json
Retry-After: 5
{
"operationId": "op-701",
"status": "pending"
}
Operation Status
GET /operations/op-701 HTTP/1.1
Host: api.example.com
Accept: application/json
{
"operationId": "op-701",
"status": "completed",
"result": {
"reportId": "report-2026-17",
"href": "/reports/report-2026-17"
}
}
Collection Filtering and Sorting
GET /orders?status=confirmed&sort=-createdAt HTTP/1.1
Host: api.example.com
Accept: application/json
The contract should define:
- Supported filter fields
- Supported operators
- Ordering syntax
- Default ordering
- Null handling
- Case sensitivity
- Maximum complexity
- Unsupported-filter behaviour
Pagination
Collection endpoints should avoid returning an unlimited number of resources.
GET /orders?limit=25&after=opaque-cursor HTTP/1.1
Host: api.example.com
Accept: application/json
{
"items": [
{
"id": 9001,
"status": "confirmed"
},
{
"id": 9002,
"status": "processing"
}
],
"page": {
"limit": 25,
"nextCursor": "opaque-next-cursor",
"hasMore": true
}
}
Cursor pagination can remain stable under concurrent inserts when the cursor and ordering contract are designed correctly.
API Versioning
Versioning provides a controlled way to introduce incompatible contract changes.
Common approaches include:
- Path versioning
- Media-type or representation versioning
- Field-based evolution without an immediate new major version
Path example:
/v1/customers/42
/v2/customers/42
Versioning should not replace compatibility discipline. Prefer additive changes when clients can safely ignore new optional fields.
Hypermedia Links
A representation can include links to related resources and supported transitions.
{
"id": 9001,
"status": "confirmed",
"links": {
"self": {
"href": "/orders/9001"
},
"customer": {
"href": "/customers/42"
},
"cancellation": {
"href": "/orders/9001/cancellation",
"method": "POST"
}
}
}
Hypermedia can reduce the need for clients to construct every related URI independently. Links must still follow documented authorization and lifecycle rules.
Rate-limit Semantics
Rate limiting protects service capacity and promotes fair usage.
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 30
{
"type": "rate-limit-exceeded",
"title": "Request rate exceeded",
"status": 429,
"detail": "Retry after the indicated delay."
}
The rate-limit contract should define:
- The limiting identity
- The operation or resource scope
- The measured time window
- Response status
- Retry guidance
- Whether limits differ by plan or caller
- How batch operations are counted
Retry Behaviour
A client should retry only when the operation, status and contract make retrying safe.
Retry candidate
|
v
Is the operation idempotent
or protected by an idempotency key?
|
+--> No:
| do not retry automatically
|
+--> Yes:
apply bounded retry
with backoff and jitter
Retry policies should include:
- Maximum attempts
- Complete operation deadline
- Exponential backoff
- Randomized jitter
- Retryable statuses
- Idempotency requirements
- Cancellation handling
Timeouts and Deadlines
Every outbound API request should have a finite deadline.
A timeout design can distinguish:
- DNS timeout
- Connection timeout
- TLS handshake timeout
- Request write timeout
- Response read timeout
- Complete operation deadline
Uncertain outcome: A client timeout does not prove that the server failed to complete the operation. State-changing APIs need idempotency or operation-status mechanisms for safe recovery.
PHP REST Controller Example
<?php
declare(strict_types=1);
header(
'Content-Type: application/json; charset=utf-8'
);
function sendJson(
int $status,
array $payload = []
): never {
http_response_code(
$status
);
if ($status !== 204) {
echo json_encode(
$payload,
JSON_THROW_ON_ERROR
);
}
exit;
}
function readJsonBody(): array
{
$contentType =
$_SERVER['CONTENT_TYPE'] ?? '';
if (
!str_starts_with(
strtolower($contentType),
'application/json'
)
) {
sendJson(
415,
[
'type' =>
'unsupported-media-type',
'title' =>
'Unsupported media type',
'status' => 415,
'detail' =>
'Use application/json.'
]
);
}
$rawBody =
file_get_contents(
'php://input'
);
if ($rawBody === false) {
sendJson(
400,
[
'type' => 'invalid-request',
'title' =>
'Unable to read request',
'status' => 400
]
);
}
try {
$data =
json_decode(
$rawBody,
true,
512,
JSON_THROW_ON_ERROR
);
} catch (
JsonException $exception
) {
sendJson(
400,
[
'type' => 'invalid-json',
'title' => 'Invalid JSON',
'status' => 400,
'detail' =>
'The request body is not valid JSON.'
]
);
}
if (!is_array($data)) {
sendJson(
400,
[
'type' =>
'invalid-request-body',
'title' =>
'Invalid request body',
'status' => 400
]
);
}
return $data;
}
$method =
$_SERVER['REQUEST_METHOD'];
if ($method !== 'POST') {
header(
'Allow: POST'
);
sendJson(
405,
[
'type' =>
'method-not-allowed',
'title' =>
'Method not allowed',
'status' => 405
]
);
}
$request =
readJsonBody();
$name =
trim(
(string)($request['name'] ?? '')
);
$email =
trim(
(string)($request['email'] ?? '')
);
$errors = [];
if ($name === '') {
$errors[] = [
'field' => 'name',
'code' => 'required',
'message' =>
'Name is required.'
];
}
if (
!filter_var(
$email,
FILTER_VALIDATE_EMAIL
)
) {
$errors[] = [
'field' => 'email',
'code' => 'invalid_format',
'message' =>
'Enter a valid email address.'
];
}
if ($errors !== []) {
sendJson(
422,
[
'type' =>
'validation-error',
'title' =>
'Request validation failed',
'status' => 422,
'errors' => $errors
]
);
}
/*
* Authorize the operation and insert the
* customer through a parameterized query.
*/
$customerId = 42;
header(
'Location: /customers/' .
$customerId
);
sendJson(
201,
[
'id' => $customerId,
'name' => $name,
'email' => $email,
'status' => 'active'
]
);
The example demonstrates content-type validation, safe JSON parsing, field-level validation and consistent responses. Production code still requires authentication, authorization, persistence, conflict handling, logging, idempotency and rate limiting.
Test REST APIs with curl
Retrieve a Resource
curl -i \
-H 'Accept: application/json' \
https://api.example.com/customers/42
Create a Resource
curl -i \
-X POST \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Idempotency-Key: test-request-1042' \
--data '{"name":"Example Customer","email":"customer@example.com"}' \
https://api.example.com/customers
Apply a Partial Update
curl -i \
-X PATCH \
-H 'Content-Type: application/merge-patch+json' \
-H 'If-Match: "customer-42-v7"' \
--data '{"status":"inactive"}' \
https://api.example.com/customers/42
Delete a Resource
curl -i \
-X DELETE \
https://api.example.com/customers/42
Replace example hosts, identifiers and credentials with approved test values. Avoid placing production credentials directly in shell history.
OpenAPI Contract
A machine-readable API description can document operations, parameters, schemas, responses and security requirements.
openapi: 3.1.0
info:
title: Customer API
version: 1.0.0
paths:
/customers/{customerId}:
get:
operationId: getCustomer
parameters:
- name: customerId
in: path
required: true
schema:
type: integer
minimum: 1
responses:
"200":
description: Customer found
content:
application/json:
schema:
$ref: "#/components/schemas/Customer"
"404":
description: Customer not found
components:
schemas:
Customer:
type: object
required:
- id
- name
- status
properties:
id:
type: integer
name:
type: string
status:
type: string
enum:
- active
- inactive
The description should match actual runtime behaviour. Contract tests can detect differences between documentation and implementation.
Observability
Useful API telemetry includes:
- Request rate
- Latency percentiles
- Status-code distribution
- Authentication failures
- Authorization rejections
- Validation failures
- Rate-limit rejections
- Idempotency-key reuse
- Dependency latency
- Request and response sizes
Logs should avoid recording passwords, access tokens, session identifiers, complete payment information or other sensitive data.
REST Troubleshooting Workflow
- Confirm the HTTP method and complete URI.
- Confirm the request content type.
- Validate the request body and parameters.
- Confirm authentication credentials.
- Confirm resource-level authorization.
- Record the status code and error response.
- Use the correlation identifier to inspect protected logs.
- Measure DNS, connection, TLS and server timing separately.
- Inspect database and dependency operations.
- Check rate limits, retries and idempotency records.
- Compare actual behaviour with the documented contract.
Common REST API Mistakes
Using Verbs in Every URI
Model stable resources through nouns and use HTTP methods to express standard operations.
Changing State through GET
GET is a safe method and should not request a business-state change.
Returning 200 for Every Outcome
Use status codes consistently so clients can distinguish success, validation, authorization, conflict and server failures.
Using Inconsistent Error Structures
A stable error contract allows clients to handle failures predictably.
Returning Unlimited Collections
Large unbounded responses increase database, memory, network and client processing cost.
Trusting Client-supplied Ownership Fields
Determine ownership and authorization from trusted identity and server-controlled resource state.
Retrying POST Blindly
A timeout can occur after the server completes the operation. Use an idempotency contract for retryable creation and payment operations.
Exposing Internal Exceptions
Stack traces, SQL statements and internal paths should not be returned to API clients.
Ignoring Concurrent Updates
Use resource versions, validators or transactional controls where lost updates are possible.
Breaking Existing Clients with Field Changes
Treat field names, types, nullability and semantics as part of the public contract.
Confusing Authentication with Authorization
A valid credential does not grant access to every resource or operation.
Logging Credentials and Sensitive Payloads
Apply explicit redaction and data-minimization rules to logs and traces.
Recommended Test Cases
| Test | Expected Evidence |
|---|---|
| Valid resource retrieval | The intended representation and status are returned |
| Missing resource | The documented not-found response is returned |
| Invalid JSON | The request is rejected through the standard error contract |
| Unsupported media type | The API returns the documented media-type failure |
| Unauthorized request | Missing or invalid credentials are rejected |
| Forbidden resource | An authenticated caller cannot access an unauthorized resource |
| Duplicate POST retry | The idempotency contract prevents duplicate effects |
| Concurrent update | A stale precondition is rejected |
| Pagination boundary | No item is unexpectedly duplicated or omitted under the defined ordering |
| Rate limit | The documented limit response and retry guidance are returned |
| Dependency failure | The API fails safely without exposing internal diagnostics |
| Contract validation | Runtime responses conform to the published API schema |
REST API Best Practices
Recommended Practices
- Model important concepts as resources.
- Use stable, predictable and noun-based resource URIs.
- Use HTTP methods according to their defined semantics.
- Return meaningful HTTP status codes.
- Use a consistent machine-readable error contract.
- Validate media types, schemas and business rules.
- Authenticate every protected request.
- Authorize every operation at the resource level.
- Use HTTPS for API communication.
- Paginate collection resources.
- Define stable sorting before implementing cursor pagination.
- Use validators to prevent lost updates.
- Use idempotency keys for safely retryable non-idempotent operations.
- Apply bounded retries with backoff and jitter.
- Set finite request deadlines.
- Document rate-limit semantics.
- Prefer additive, backward-compatible contract evolution.
- Maintain a machine-readable API description.
- Test runtime behaviour against the published contract.
- Redact credentials and sensitive content from telemetry.
Practice Exercise
Design and implement a versioned REST API for customer and order resources.
Requirements
- Create customer collection and item resources.
- Create order collection and item resources.
- Use GET, POST, PUT, PATCH and DELETE appropriately.
- Validate JSON media types.
- Return a consistent error representation.
- Require authentication for protected operations.
- Authorize access at customer and order level.
- Support cursor pagination for order collections.
- Support filtering by order status.
- Apply stable ordering.
- Use ETags for conditional retrieval and updates.
- Use idempotency keys for order creation.
- Apply request-size and rate limits.
- Publish an OpenAPI contract.
- Create automated contract and authorization tests.
Endpoint Design
| Method | Endpoint | Purpose |
|---|---|---|
| GET | /v1/customers |
List customers through bounded pagination |
| POST | /v1/customers |
Create a customer |
| GET | /v1/customers/{customerId} |
Retrieve one customer |
| PUT | /v1/customers/{customerId} |
Replace customer state |
| PATCH | /v1/customers/{customerId} |
Modify selected customer fields |
| DELETE | /v1/customers/{customerId} |
Delete or deactivate a customer according to contract |
| GET | /v1/customers/{customerId}/orders |
List the customer's orders |
| POST | /v1/orders |
Create an order using an idempotency key |
| GET | /v1/orders/{orderId} |
Retrieve one order |
Frequently Asked Questions
What is REST?
REST is an architectural style for distributed systems based on resources, representations, uniform interactions, stateless requests and other architectural constraints.
Is every JSON API a REST API?
No. JSON is a representation format. REST concerns resource modelling, interaction semantics and architectural constraints.
Should REST endpoint names use verbs?
Resource endpoints normally use nouns, while HTTP methods express standard operations. Domain actions can be modelled as action or process resources when they do not fit ordinary create, retrieve, replace or delete semantics.
What is the difference between PUT and PATCH?
PUT creates or replaces the target resource's state using the supplied representation. PATCH applies a partial modification according to its defined patch semantics.
What does stateless mean in REST?
Each request contains the information needed to understand and process it without depending on undocumented conversational state from an earlier request.
What is an idempotent operation?
An idempotent operation has the same intended effect when the identical request is applied once or several times.
Should POST requests be retried automatically?
Not unless the operation supports a documented idempotency mechanism or another contract that makes the retry safe.
What status should creation return?
A successful creation can return 201 Created and identify the
new resource through Location.
Why should collection endpoints be paginated?
Pagination bounds database, memory, serialization, network and client-side processing cost.
What is an ETag?
An ETag is a validator that can support cache revalidation and conditional updates.
Does authentication provide authorization?
No. Authentication establishes a caller identity. Authorization determines whether that caller may perform the requested operation.
What comes after REST?
The next topic is RPC and gRPC, followed by GraphQL and resource modelling.
Key Takeaway
REST APIs model application concepts as resources and use HTTP methods, fields, representations and status codes consistently. A production API contract should define validation, errors, authentication, resource-level authorization, pagination, caching, conditional updates, retries, idempotency, rate limits and compatibility. Keep requests self-contained, use HTTPS, bound all collections and payloads, document the contract in a machine-readable format and verify that runtime behaviour matches the published specification.