API Design
REST/GRPC/GraphQL
Rest
Mostly go with Rest
Resource oriented
Resources should be noun with plural form like events, tickets.
When core entities have relationship, use nested structure for the resource uri.
Data can be passed based on path-param, query-param and request body.
SafeCannot change state of server on invocation
GET, TRACE, OPTION, HEAD are safe because
IdempotentMultiple invocation (duplicate calls on try) on a resource will leave them in same state.
PUT, DELETE, GET are idempotent
Status codes
Ensure relevant status code is communicated based on operation
SUCCESS
200,201,202,204
FAILURE
Client
400,401,402,403,404,405,406,409,415,429
Server
500,501,502,503,504
GRPC
Only use GRPC for internal microservice communication.
Action oriented (think in terms of action and procedure).
Consider only when high performance is needed.
Binary Serialization and deserialization.
Uses HTTP/2 as transport protocol.
Offers type safety.
Supports streaming server-side, client-side and bidirectional
GraphQL
API Patterns
Pagination
Offset based
Works for most scenarios, simplest approach
But can lead to problems if data gets added.removed while user is performing pagination
User may see duplication entries or miss entries.
Does not scale for large datasets.
Easy to implement jump to specific page number.
Cursor based
Solves all the offset based pagination problems
But it is not easy to implement jump to a specific page number.
This is because cursor only offers/holds next page reference.
Use case include real-time data pagination or high-volume of data.
Versioning
URL versioning
widely accepted
Header versioning
Security
Authentication
Answer who is making API invocation
Authorization
Verified permission of invoker
API Keys v/s JWT
API Key
API keys are long, randomly generated strings that act like passwords for applications rather than humans.
When a client makes a request, they include their API key in the Authorization header, and server looks up that key to identify which application is making the request.
Store it in a database along with any permissions or rate limits for that client, and then verify each incoming request by looking up the key.
They're perfect for server-to-server communication where you control both sides.
A user-facing product with user-facing APIs, API keys are almost never the right choice.
Use API keys for internal service communication and external developer access.
JWT
JWT tokens, encode user information directly into the token itself rather than storing session state on your server.
When a user logs in successfully, your server creates a JWT containing their user ID, permissions, and an expiration time, then signs the entire token with a secret key.
When that JWT comes back with future requests, you can verify it's authentic by checking the signature, and you can read the user information directly from the token without any database lookups. The token itself carries all the context you need to authorize the request.
Works particularly well for distributed systems because any service with access to the verification key can validate tokens independently.
RBAC (Authorization)
Real systems have different types of users with different permissions.
RBAC assigns roles to users and permissions to roles.
Rate Limiting & Throttling
Rate limiting prevents abuse by restricting how many requests a client can make in a given time period. Enforces fairness.
This protects your system from both malicious attacks and accidental overuse.
Typically implement rate limiting at the API gateway level or using middleware in your application.
When limits are exceeded, return a 429 Too Many Requests status code.
Strategies include
Per-user limits: 1000 requests per hour per authenticated user
Per-IP limits: 100 requests per hour for unauthenticated requests
Endpoint-specific limits: 10 booking attempts per minute to prevent ticket scalping.
Throttling allows to acheive stability.
Last updated