Two APIs can do the same job — one is a joy to use, the other a daily frustration. The difference is rarely cleverness; it's care in a handful of decisions: how you name things, how you report errors, how you handle change and security. This course is those decisions, with the standards to lean on. It will make any API you build (or judge) better.
- Name and structure resources so an API reads like plain English
- Report errors in a way that helps the caller fix the problem
- Handle change safely with versioning, and protect the API with auth
- Make your API self-explanatory with documentation and a standard spec
Name things like a human would
A well-named API is almost self-explanatory. The core REST convention: resources are nouns, addressed by URL; the verb lives in the HTTP method, not the name.
| Don't | Do | Why |
|---|---|---|
GET /getUser?id=42 | GET /users/42 | The verb is already GET — don't repeat it |
POST /createOrder | POST /orders | POST already means "create" |
GET /user_list | GET /users | Collections are plural nouns |
POST /users/42/deactivate | POST /users/42/deactivation | Even actions read as resources |
The test: read the method + path aloud. DELETE /users/42 says "delete user 42." If it reads like a sentence, you've named it well. Consistency matters as much as the rules — pick plural nouns, lowercase, hyphens-not-underscores, and never break the pattern.
- Resources are plural nouns in the URL; the action is the HTTP method
GET /users/42, notGET /getUser?id=42— don't repeat the verb- Pick one convention and follow it everywhere — predictability is the feature
Errors that help, not haunt
When something goes wrong, your error response is the only thing the caller has to work with. A good one turns a frustrated developer into a productive one. A bad one — a bare 400 with no explanation — turns them into a support ticket.
Three things every error should do:
- Use the right status code so machines can react (
400bad input,401not logged in,403not allowed,404not found,429too many requests,500our fault). - Say what went wrong, in plain language — "email is required" beats "validation error."
- Help them fix it — point at the field, the limit, the next step.
{
"error": "invalid_request",
"message": "The 'email' field is required.",
"field": "email"
}
- An error response is a product surface — design it to help the caller fix the problem
- Use the right status code, explain in plain language, point at the fix
- There's a standard error shape worth following (RFC 9457)
- Rewrite
GET /fetchAllProductsandPOST /deleteUser?id=9as clean REST endpoints. - What three things should a good error response always do?
Versioning — change without breaking people
Here's a hard truth: the moment other people depend on your API, you can't freely change it. Rename a field and every app using it breaks. But you also can't freeze forever. The answer is versioning — running the old shape and the new shape side by side.
The common, readable approach is to put the version in the path: GET /v1/users/42 and GET /v2/users/42. Existing apps stay on v1 and keep working; new apps adopt v2. You give people time to move, then retire the old version on a clear schedule.
- Once others depend on your API, you can't change it freely
- Versioning runs old and new side by side (e.g.
/v1/,/v2/) - Plan for change: version early, deprecate with plenty of warning, never break silently
Security — who's calling, and what may they do?
Most APIs shouldn't answer just anyone. Two questions sit at the heart of API security:
- Authentication — who are you? The caller proves their identity, usually with a secret API key or a token.
- Authorisation — what are you allowed to do? Even an identified caller shouldn't be able to do everything. A read-only key can fetch but not delete.
For anything beyond a simple key, the industry standard is OAuth 2.0 — the mechanism behind every "Log in with Google" button. It lets an app act for a user with limited, revocable permission, and without ever seeing the user's password.
- Authentication = who you are (API key or token); authorisation = what you may do
- Apply least privilege — a key should only do what its job needs
- Use OAuth 2.0 for user-delegated access; always use HTTPS; never leak secrets
Documentation — an API nobody can read doesn't exist
The best-designed API is useless if a developer can't figure out how to call it. Documentation isn't an afterthought; it's how your API gets adopted. And the good news: you can largely generate it.
The standard is the OpenAPI Specification (you may know its old name, Swagger). You describe your API once in a structured file — every endpoint, input, and response — and tools turn that into interactive documentation developers can read and try in the browser, plus client code in many languages.
- Documentation is how an API gets adopted — not optional
- Describe your API once in OpenAPI; generate interactive docs and client code from it
- Every principle here reduces to one: the developer calling your API is your customer
- Why can't you freely rename a field once others use your API, and what's the fix?
- What's the difference between authentication and authorisation? Give an example of each.
- What does describing your API in OpenAPI get you "for free"?