Building Better APIs: Lessons Learned
APIs are contracts. And like any contract, how you write them matters enormously. After building dozens of APIs and consuming hundreds more, I’ve learned some lessons worth sharing.
Consistency is Everything
The single most important principle in API design is consistency. If you use camelCase for one field, use it everywhere. If you return errors in a certain format, stick to it.
// Good - consistent structure
{
"data": { "userId": 123, "userName": "Saksham" },
"meta": { "requestId": "abc-123" }
}
// Bad - inconsistent naming
{
"data": { "user_id": 123, "UserName": "Saksham" }
}
Consistency reduces cognitive load. Developers can predict how your API behaves without checking documentation for every endpoint.
Design for the Consumer
Before writing any code, ask: “Who will use this API and how?”
A mobile app might need:
- Minimal payloads (bandwidth matters)
- Offline-friendly design
- Fast response times
An internal service might need:
- Detailed error information
- Bulk operations
- Flexible querying
Design decisions should flow from understanding your consumers.
Error Handling Done Right
Good error responses are specific, actionable, and consistent:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid request parameters",
"details": [
{
"field": "email",
"message": "Must be a valid email address"
}
]
}
}
Key principles:
- Machine-readable codes for programmatic handling
- Human-readable messages for debugging
- Specific details about what went wrong
- Consistent structure across all error types
Versioning Strategy
APIs evolve. How you handle versioning affects everyone who depends on you.
My preferred approach is URL versioning:
GET /v1/users
GET /v2/users
It’s explicit, simple, and works with standard HTTP caching. The alternatives (header-based versioning, query parameters) add complexity without clear benefits.
Pagination Patterns
For list endpoints, cursor-based pagination beats offset pagination:
{
"data": [...],
"pagination": {
"nextCursor": "eyJpZCI6MTIzfQ==",
"hasMore": true
}
}
Offset pagination breaks when items are added or removed during pagination. Cursors provide stable, consistent results.
Documentation as a Feature
Great documentation isn’t optional. It’s part of the product.
What good API docs include:
- Quick start guide
- Authentication examples
- Every endpoint with request/response samples
- Error codes and their meanings
- Rate limit information
Tools like OpenAPI/Swagger help, but nothing replaces well-written explanations and realistic examples.
Final Thoughts
Building good APIs is a skill developed over time. The best APIs I’ve worked with share common traits: they’re consistent, well-documented, and clearly designed with their consumers in mind.
Take time to get the fundamentals right. Your API’s consumers - including future you - will appreciate it.