← Programming Fundamentals That Actually Matter
Lesson 10 of 10

API Design: What Makes an API Good or Bad

SoftwareAdvanced

An API Is a Promise to Every Future Caller

Once something calls your API in production, every field name, status code, and behavior becomes something you can't casually change without breaking someone - even if "someone" is just your own frontend six months from now, after you've forgotten the details. Good API design is mostly about making that promise as small, clear, and stable as possible.

text
Bad:  GET /getUserData?userid=42&format=json
Good: GET /users/42

Bad:  200 OK  {"error": "user not found"}
Good: 404 Not Found  {"error": "user not found"}

Bad:  a field silently renamed from "name" to "fullName" in v1
Good: a new /v2/ path, with /v1/ kept working until callers migrate

REST's actual convention: resources are nouns in the URL (`/users/42`), actions are HTTP methods (GET to read, POST to create, PUT/PATCH to update, DELETE to remove) - not verbs stuffed into the path (`/getUser`, `/deleteUser`). Status codes should reflect what actually happened, not just always return 200 with an error buried in the body - that breaks caching, monitoring, and every HTTP client's built-in error handling.

Versioning matters the moment more than one client depends on your API. It doesn't need to be elaborate - even "the old behavior keeps working at /v1/ while a genuinely breaking change ships at /v2/" beats silently changing a response shape underneath every existing caller and hoping nothing downstream breaks.