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.

  • Safe

    • Cannot change state of server on invocation

    • GET, TRACE, OPTION, HEAD are safe because

  • Idempotent

    • Multiple 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

  1. 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.

  2. 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