Development10 min readMay 8, 2024

API Design Best Practices: Building APIs Developers Love

E. Lopez

CTO

API Design Best Practices: Building APIs Developers Love

A well-designed API is a joy to work with. A poorly designed one creates frustration, bugs, and integration headaches. Here are the principles we follow when designing APIs that developers love.

Consistency Above All

The most important quality of an API is consistency. Developers should be able to guess how unfamiliar endpoints work based on how familiar ones work.

Naming Conventions

Pick a naming convention and stick with it everywhere. Decide whether you use camelCase or snake_case, plural or singular resource names, and apply it uniformly.

Response Structures

Every successful response should follow the same structure. Every error should follow the same structure. Developers should never wonder what shape the data will take.

HTTP Methods

Use HTTP methods semantically. GET for retrieval, POST for creation, PUT/PATCH for updates, DELETE for removal. Never use GET for operations with side effects.

Resource-Oriented Design

Think in terms of resources, not operations. Instead of createUser and updateUser endpoints, have a users resource that responds to different HTTP methods.

URL Structure

URLs should describe the resource hierarchy. /users/123/orders/456 clearly communicates that order 456 belongs to user 123.

Avoid Verbs in URLs

URLs should be nouns. Instead of /api/getUsers, use /api/users. Instead of /api/sendEmail, use /api/emails with a POST method.

Error Handling

Errors are as much a part of your API as successful responses. Design them carefully.

HTTP Status Codes

Use status codes correctly. 400 for validation errors, 401 for authentication failures, 403 for authorization failures, 404 for missing resources, 500 for server errors.

Error Response Structure

Include enough information for developers to understand and fix the problem. A good error response includes an error code, a human-readable message, and details about what specifically failed.

Validation Errors

For validation errors, return information about all failing fields, not just the first one. Developers should not have to submit repeatedly to discover all validation issues.

Pagination

Any endpoint that returns a list should support pagination. Eventually, that list will grow larger than clients can handle.

Cursor-Based Pagination

For most use cases, cursor-based pagination is superior to offset-based. It handles real-time additions gracefully and performs better at scale.

Pagination Metadata

Include total counts when practical, links to next and previous pages, and clear indication of whether more results exist.

Filtering and Sorting

Give clients control over what data they receive. This reduces payload size and eliminates the need for client-side processing.

Query Parameters

Use query parameters for filtering. Keep the parameter names consistent with your resource field names.

Sort Parameter

Support sorting with a clear syntax. Indicate sort direction explicitly, whether through +/- prefixes or separate direction parameters.

Versioning

APIs evolve. Plan for versioning from the start.

URL Versioning

Include version in the URL path (/v1/users). It is explicit and easy to understand. This is our preferred approach.

Header Versioning

Some APIs use custom headers for versioning. This keeps URLs cleaner but is less discoverable.

Maintain Backward Compatibility

Within a version, never make breaking changes. Additive changes are safe—removing or renaming fields is not.

Documentation

Documentation is part of your API. Treat it with the same care as your code.

OpenAPI Specification

Document your API with OpenAPI (Swagger). This enables automatic documentation, code generation, and testing tools.

Examples

Include real examples for every endpoint. Developers learn by example more than by reading specifications.

Error Documentation

Document the errors each endpoint can return. Developers need to handle these cases in their code.

Authentication and Security

Use Standard Mechanisms

Implement OAuth 2.0 or JWT tokens. Do not invent custom authentication schemes.

Rate Limiting

Protect your API with rate limiting. Return clear headers indicating limits and current usage.

Always Use HTTPS

There is no excuse for APIs that accept HTTP connections. Encrypt everything.

GraphQL Considerations

GraphQL is an alternative to REST that solves some problems elegantly while creating others.

When to Use GraphQL

GraphQL shines when clients need flexible queries across related data. Mobile apps with bandwidth constraints often benefit.

When to Stick with REST

For simpler APIs, CRUD operations, and public APIs, REST is often simpler to implement and consume.

Conclusion

API design is a form of UX design for developers. Consistency, clear error handling, and comprehensive documentation make the difference between an API that developers enjoy working with and one they tolerate. Invest the time upfront—API changes are expensive once clients depend on them.

#API#REST#GraphQL#Backend

About E. Lopez

CTO at DreamTech Dynamics