Modern websites are usually split into two parts:
- Front-end (client): Runs in the browser (HTML, CSS, JavaScript).
- Back-end (server): Runs on a server and handles data, business rules, authentication, and integration with databases or other services.
A well-designed API (Application Programming Interface) is the “contract” between the front-end and the back-end.
1) What a Server Does (in a Web Context)
A web server application listens for requests from clients (usually browsers or mobile apps) and sends back responses.
Typical responsibilities include:
- Routing requests to the right handler (e.g.
/api/products→ “list products”). - Validating inputs (e.g. checking required fields).
- Authorisation (checking what the user is allowed to do).
- Reading/writing data (via a database).
- Returning consistent responses (usually JSON for APIs).
- Handling errors safely (not leaking sensitive details).
The request–response cycle
- The client sends an HTTP request (method + URL + headers + optional body).
- The server matches the request to a route.
- The server runs logic and returns an HTTP response (status code + headers + body).
2) Routing Basics
Routing is how your server decides what code runs for a given URL and HTTP method.
A route is usually made up of:
- Method:
GET,POST,PUT,PATCH,DELETE - Path:
/api/users,/api/users/:id
Example route patterns:
GET /api/products→ list all productsGET /api/products/123→ get product 123POST /api/products→ create a productPATCH /api/products/123→ update part of product 123DELETE /api/products/123→ delete product 123
Route parameters vs query parameters
-
Route parameter (part of the path):
/api/products/123→123is the product ID
Used to identify a specific resource. -
Query parameter (after
?):
/api/products?category=shoes&page=2
Used for filtering, sorting, pagination, searching.
Good practice:
- Use route params for identity (
/api/orders/:orderId) - Use query params for options (
?sort=price&direction=asc)
3) HTTP Request Methods (Verbs)
RESTful APIs use standard HTTP methods to describe actions:
GET (Read)
- Fetch data.
- Should not change server state.
- Examples:
GET /api/usersGET /api/users/42
POST (Create)
- Create a new resource.
- Sends data in the request body (typically JSON).
- Example:
POST /api/userswith body{ "email": "...", "password": "..." }
PUT (Replace)
- Replace an entire resource (full update).
- Example:
PUT /api/users/42with a complete user object
- If you omit a field, it may be overwritten/removed depending on implementation.
PATCH (Partial update)
- Update part of a resource.
- Example:
PATCH /api/users/42with body{ "displayName": "Sipho" }
DELETE (Remove)
- Remove a resource.
- Example:
DELETE /api/users/42
4) RESTful Endpoint Design Principles
REST (Representational State Transfer) is a style for designing APIs around resources.
4.1 Use nouns, not verbs, in URLs
Prefer:
/api/products/api/products/123
Avoid:
/api/getProducts/api/createProduct
The HTTP method already tells you the action.
4.2 Use consistent plural naming
Pick one style and stick to it:
- Common:
/api/products,/api/users,/api/orders
4.3 Design around resource relationships
Examples:
- Products have reviews:
GET /api/products/123/reviewsPOST /api/products/123/reviews
Users have orders:
GET /api/users/42/orders
Keep nesting reasonable (don’t go too deep). If it becomes confusing, consider linking via query parameters:
GET /api/orders?userId=42
4.4 Filtering, sorting, pagination
Use query parameters:
- Filter:
GET /api/products?category=shoes - Search:
GET /api/products?search=running - Sort:
GET /api/products?sort=price&direction=asc - Pagination:
GET /api/products?page=2&pageSize=20
Make your pagination behaviour clear and consistent. For example, always return:
items(array)page,pageSizetotalItems(ortotalPages)
4.5 Version your API (when needed)
For public or long-lived APIs, versioning helps you change things safely:
/api/v1/products
Avoid breaking changes where possible. If you must break, do it in a new version.
5) HTTP Status Codes You Should Know
Status codes tell the client what happened, in a standard way.
Success responses
- 200 OK: Request succeeded (common for
GET,PATCH) - 201 Created: Resource created (common for
POST) - 204 No Content: Success with no response body (common for
DELETE)
Client errors (the client did something wrong)
- 400 Bad Request: Invalid input (missing fields, wrong formats)
- 401 Unauthorized: Not logged in / missing or invalid authentication
- 403 Forbidden: Logged in, but not allowed to access this resource
- 404 Not Found: Resource doesn’t exist
- 409 Conflict: Conflict with current state (e.g. duplicate email)
- 422 Unprocessable Content: Valid JSON but failed business validation (optional; some teams use 400 instead)
Server errors (the server failed)
- 500 Internal Server Error: Unexpected error
- 503 Service Unavailable: Server is overloaded or down for maintenance
Good practice:
- Be consistent in what you return for similar situations.
- Don’t use
200for errors. Let status codes do their job.
6) Request and Response Format (JSON)
Most REST APIs use JSON.
Example request:
POST /api/products
Content-Type: application/json
Authorization: Bearer <token>
{
"name": "Running Shoes",
"price": 999.99,
"inStock": true
}
Example response:
HTTP/1.1 201 Created
Content-Type: application/json
{
"id": "p_123",
"name": "Running Shoes",
"price": 999.99,
"inStock": true,
"createdAt": "2026-03-12T10:15:00Z"
}
Good practice:
- Always set and check
Content-Type: application/jsonwhen sending JSON. - Use consistent naming (e.g.
camelCase) across the whole API. - Return stable identifiers (IDs) for resources.
7) Error Handling Patterns (Clear and Safe)
Errors are normal. What matters is returning errors that are:
- Understandable for the front-end
- Consistent across endpoints
- Safe (no leaked stack traces or secrets)
A common error format:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Price must be a positive number.",
"details": [
{ "field": "price", "issue": "must be greater than 0" }
]
}
}
Guidelines:
- Keep
messageuser-friendly (or at least developer-friendly). - Use
codevalues the front-end can handle (e.g. show a specific message, highlight a field). - Only include
detailswhen helpful (especially for form validation).
Validation errors
Return:
- 400 (or 422) with field-level details.
Not found
Return:
- 404 with a clear message like “Product not found”.
Authentication/authorisation failures
Return:
- 401 when not logged in or token invalid.
- 403 when logged in but not allowed.
Unexpected errors
Return:
- 500 with a generic message:
- “Something went wrong.”
- Log technical detail on the server (for debugging), not in the response.
8) Designing Endpoints for Smooth Front-end Integration
Your front-end developers (including future you) will thank you for consistency.
8.1 Make responses predictable
For example, always return:
- a single object for single-resource endpoints
- arrays for list endpoints
- the same field names everywhere
Example:
GET /api/products/123returns{ id, name, price }GET /api/productsreturns{ items: [ ... ], page, pageSize, totalItems }
8.2 Avoid over-fetching and under-fetching
- Over-fetching: returning too much data the UI doesn’t need.
- Under-fetching: forcing the UI to call 5 endpoints for one page.
Balance ideas:
- Provide “list views” with summary fields and “detail views” with full fields.
- Consider query options like
?include=reviewsonly if your team agrees and documents it clearly.
8.3 Handle empty states cleanly
If there are no products, the list endpoint should return:
- 200 OK
items: []
Not an error.
8.4 Idempotency (important for reliability)
Some requests should be safe to repeat:
GET,PUT,DELETEare typically idempotent (repeating should not change the outcome).POSTis usually not idempotent (repeating may create duplicates).
This matters for retries when networks are unreliable.
9) Quick Example: A Small REST API for Products
A simple, clear set of endpoints:
-
GET /api/products
List products (supports?page=1&pageSize=20&search=...) -
POST /api/products
Create a product -
GET /api/products/:id
Fetch one product -
PATCH /api/products/:id
Update fields (e.g. price or stock) -
DELETE /api/products/:id
Remove product
Potential responses:
- On create success:
201 Created+ new product JSON - On delete success:
204 No Content - On invalid data:
400 Bad Request+ validation details - On missing product:
404 Not Found
10) Checklist: REST Design and Server Behaviour
Use this as a quality check when you build APIs:
- [ ] Routes use nouns and consistent naming (usually plural).
- [ ] HTTP methods match the action (
GET,POST,PATCH,DELETE). - [ ] Status codes are correct and consistent.
- [ ] Errors return a consistent JSON structure.
- [ ] Validation is handled with helpful field-level messages.
- [ ] Pagination/filtering/sorting use query parameters.
- [ ] Sensitive server details are not exposed in responses.
- [ ] API behaviour is predictable for the front-end (stable fields and formats).
If you want, I can also provide a small “API contract” template (endpoint + request + response examples) you can include in your project documentation for the LMS.