A REST API is an interface between software systems. A good API should be predictable, secure, versionable, and consistent.
The quality of an API depends on much more than simply returning JSON from HTTP endpoints.
URLs should represent resources rather than actions.
For example:
GET /users/42
represents retrieving a user.
Creating a user can use:
POST /users
Updating a user can use:
PATCH /users/42
This creates a consistent mental model for consumers.
Status codes communicate the result of an operation.
Common examples include:
200 for successful retrieval or operation.
201 when a resource has been created.
400 when the request is invalid.
401 when authentication is required.
403 when the authenticated user lacks permission.
404 when the requested resource does not exist.
409 when the operation conflicts with current state.
500 for unexpected server failures.
Consistent status codes make APIs easier to consume.
Returning thousands of records in a single request is inefficient.
Pagination allows clients to retrieve data incrementally.
An API may expose parameters such as page and pageSize or cursor-based pagination.
Cursor pagination is often preferable for rapidly changing datasets because it avoids some problems caused by records being inserted while a user is navigating through pages.
APIs often need to support:
These parameters should be predictable and validated.
For example:
GET /projects?status=active&sort=-createdAt&pageSize=20
The server should validate allowed fields instead of accepting arbitrary database expressions.
Idempotency is particularly important for operations that can be retried.
A client may send the same request twice because of a network timeout.
For payment-like operations, the server should be able to recognize duplicate requests and avoid performing the same operation twice.
API security should include:
Authentication answers who the user is.
Authorization answers what that user is allowed to do.
These are different concerns and both are required.
APIs change over time.
Versioning allows existing consumers to continue working while a new contract is introduced.
The important goal is to avoid breaking existing clients unnecessarily.
A robust REST API is therefore a carefully designed contract rather than a collection of database endpoints.