API-first means you design and agree on the API contract before writing implementation code. Not "we'll document the API after we build it" - the API design is the first artifact, and it drives everything else.
Why API-First, Not Code-First
Code-first problem: Developer builds the backend, then documents what they built. Frontend team waits for the backend to be done before starting. Result: 6 weeks of sequential work that could have been parallel.
API-first approach: Team agrees on the API contract (endpoints, request/response shapes, error codes) in week 1. Then:
- Backend team implements against the contract
- Frontend team builds against mock responses from the contract
- Both happen in parallel
Same 6 weeks of work becomes 3-4 weeks.
What the Contract Looks Like
OpenAPI (formerly Swagger) is the standard:
# openapi.yaml
openapi: 3.0.0
paths:
/orders:
post:
summary: Create an order
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [items, shippingAddress]
properties:
items:
type: array
items:
type: object
properties:
productId: { type: string }
quantity: { type: integer, minimum: 1 }
shippingAddress:
$ref: '#/components/schemas/Address'
responses:
'201':
description: Order created
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
'400':
description: Invalid request
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
This contract is:
- Machine-readable → can generate TypeScript types, client SDKs, mocks
- Executable → mock server runs from this file
- Documentable → Swagger UI, Redoc auto-generate beautiful docs
- Testable → validation tools verify implementation matches contract
Tools for API-First Development
Design
- Stoplight Studio - visual API designer, generates OpenAPI
- Insomnia Designer - design + test in one tool
- Manual editing in YAML (fine once you know OpenAPI)
Mock Servers
Mock server serves fake responses from the OpenAPI spec, so frontend team can develop without waiting for backend:
# Prism mock server
npx @stoplight/prism-cli mock ./openapi.yaml
# Now frontend can call http://localhost:4010/orders
# Gets realistic responses based on spec
Type Generation
Generate TypeScript types from the spec - eliminates entire class of bugs:
# openapi-typescript
npx openapi-typescript ./openapi.yaml -o ./types/api.ts
Result:
// Auto-generated, always in sync with API
export interface CreateOrderRequest {
items: { productId: string; quantity: number }[];
shippingAddress: Address;
}
export interface Order {
id: string;
status: 'pending' | 'processing' | 'shipped' | 'delivered';
total: number;
// ...
}
Contract Testing
Verify the running API matches the spec:
# Dredd - runs your test suite against OpenAPI spec
npx dredd ./openapi.yaml http://localhost:3000
API Design Principles
Resource-Oriented URLs
# Good
GET /users/{id}
POST /orders
DELETE /orders/{id}
PATCH /orders/{id}
# Bad
GET /getUser?id=123
POST /createOrder
POST /deleteOrder
POST /updateOrderStatus
Consistent Error Format
Every error response should look the same:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid request",
"details": [
{ "field": "quantity", "message": "Must be at least 1" }
]
}
}
Never return plain strings or different shapes depending on the error type.
Versioning
Put the version in the URL: /v1/orders, /v2/orders. Never break existing clients by changing a v1 endpoint.
Pagination
Pick one pattern and use it everywhere:
// Cursor-based (preferred for large datasets)
{
"data": [...],
"pagination": {
"nextCursor": "eyJpZCI6MTAwfQ==",
"hasMore": true
}
}
API-First for Internal vs External APIs
Internal APIs (frontend ↔ backend in your product): API-first primarily benefits development velocity and type safety.
External APIs (your product as a platform): API-first is critical. External developers depend on your API not changing unexpectedly. Breaking changes need versioning. Documentation needs to be excellent.
If you're building a product where third parties integrate with you: treat your API design with the same care as your UI design. It's a user interface - for developers.
Common API Design Mistakes
Returning 200 for errors - use HTTP status codes correctly: 400 (client error), 401 (unauthorized), 403 (forbidden), 404 (not found), 500 (server error)
Inconsistent naming -
userId,user_id,UserIDin the same APINo pagination - endpoint returns all 50,000 records
Leaking implementation details - returning raw database column names, internal IDs, infrastructure details
No idempotency keys - POST endpoints that create resources should accept an idempotency key to prevent duplicate creates on retry
Design your API with Aunimeda →
Aunimeda develops websites and web applications for businesses - corporate sites, e-commerce, portals, and custom platforms.
Contact us to discuss your web project. See also: Web Development, E-commerce Development