API Design¶
Good API design is consistent, intuitive, and versioned. REST — resource-oriented, HTTP verbs (GET/POST/PUT/DELETE), stateless, widely used. GraphQL — client specifies exact data shape, single endpoint, reduces over/under-fetching. gRPC — binary protocol (protobuf), high performance, streaming, used for service-to-service communication. Choose REST for public APIs, gRPC for internal microservices, GraphQL for flexible client needs.
RESTful API Best Practices¶
REST APIs are resource-oriented — use nouns (/users), not verbs. Map HTTP methods to CRUD: GET (read), POST (create), PUT (replace), PATCH (partial update), DELETE (remove). Use proper HTTP status codes, pagination (?page=0&size=20), filtering (?status=ACTIVE), and versioning (/api/v1/). Always use HTTPS.
Deep Dive: Resource Naming & Status Codes
Resource naming (nouns, not verbs):
GET /api/users → List users
GET /api/users/123 → Get user 123
POST /api/users → Create user
PUT /api/users/123 → Replace user 123
PATCH /api/users/123 → Partial update user 123
DELETE /api/users/123 → Delete user 123
GET /api/users/123/orders → Get orders for user 123
HTTP status codes: | Code | Meaning | When | |------|---------|------| | 200 | OK | GET/PUT success | | 201 | Created | POST success | | 204 | No Content | DELETE success | | 400 | Bad Request | Validation error | | 401 | Unauthorized | Not authenticated | | 403 | Forbidden | Not authorized | | 404 | Not Found | Resource doesn't exist | | 409 | Conflict | Duplicate resource | | 429 | Too Many Requests | Rate limited | | 500 | Internal Server Error | Server bug |
Deep Dive: Pagination, Filtering & Versioning
Pagination:
GET /api/users?page=0&size=20&sort=createdAt,desc
Response:
{
"content": [...],
"totalElements": 100,
"totalPages": 5,
"number": 0,
"size": 20
}
Filtering & searching:
Versioning:
REST vs GraphQL vs gRPC¶
REST — simple, cacheable, great for public APIs. GraphQL — client defines exact data shape in a single query, eliminates over/under-fetching, great for complex front-ends. gRPC — binary protocol using protobuf, supports streaming, excellent performance, best for internal service-to-service calls. REST is most common; use others when their strengths match your problem.
Deep Dive: Comparison & Examples
| Feature | REST | GraphQL | gRPC |
|---|---|---|---|
| Protocol | HTTP/JSON | HTTP/JSON | HTTP/2 + Protobuf |
| Data fetching | Fixed structure | Client specifies | Defined in .proto |
| Over-fetching | Common | No | No |
| Under-fetching | Common (multiple calls) | No (single query) | No |
| Performance | Good | Good | Excellent |
| Caching | Easy (HTTP cache) | Harder | Harder |
| Best for | Public APIs | Flexible front-ends | Internal microservices |
GraphQL example:
gRPC example:
Idempotency¶
An operation is idempotent if performing it multiple times has the same effect as once. GET, PUT, DELETE are idempotent. POST is not — sending twice may create duplicates. Make POST idempotent using an Idempotency-Key header — server checks if already processed and returns cached result.
Deep Dive: Idempotency Table & Fix
| Method | Idempotent? | Safe? |
|---|---|---|
| GET | ✅ | ✅ |
| PUT | ✅ | ❌ |
| DELETE | ✅ | ❌ |
| POST | ❌ | ❌ |
| PATCH | ❌ | ❌ |
Making POST idempotent:
API Authentication & Security¶
Common auth methods: API Key (simple header token for third-party APIs), JWT (stateless signed token for modern apps), OAuth 2.0 (delegated authorization for social login), mTLS (mutual certificates for service-to-service). Always use HTTPS, validate all inputs, rate-limit, and follow least privilege.
Deep Dive: Comparison
| Method | Description | Use Case |
|---|---|---|
| API Key | Simple token in header | Third-party APIs |
| JWT (Bearer Token) | Stateless, signed token | Modern apps |
| OAuth 2.0 | Delegated authorization | Social login |
| mTLS | Mutual TLS certificates | Service-to-service |
Common Interview Questions¶
Common Interview Questions
- What makes a good REST API?
- What HTTP status codes should you use for different scenarios?
- What is the difference between PUT and PATCH?
- What is idempotency? Why is it important?
- REST vs GraphQL vs gRPC — when to use each?
- How do you version an API?
- How do you handle pagination?
- How do you secure a REST API?