Skip to main content

WHAT MAKES AN API “GOOD”?

A good API is:

  • Predictable

  • Consistent

  • Discoverable

  • Typed (implicitly or explicitly)

  • Versionable

  • Secure

  • Backwards-compatible

  • Composable

  • Idempotent

  • Well-bounded

A great API feels like it “could not have been built any other way.”

This is what you should aim for.


API DESIGN FUNDAMENTALS

Most engineers jump into endpoint creation.

Top engineers start with domain modeling and resource boundaries.


Model 1 — Resource-Oriented Design (Stripe Style)

Stripe popularized the cleanest approach:

Every domain object is a noun:

POST   /v1/customers
GET /v1/customers/{id}
POST /v1/customers/{id}/sources

Characteristics:

  • consistent nesting

  • predictable actions

  • minimal verbs

  • nouns represent real domain actors

Use this model unless you have a reason not to.


Model 2 — Action-Oriented Design (Slack Style)

Used when resources don’t cleanly represent actions:

POST /chat.postMessage
POST /users.list
POST /conversations.rename

Useful for:

  • RPC-style APIs

  • internal services

  • operations that don’t map to REST nicely


Model 3 — Hybrid Design

Most companies use a hybrid.

Example:

Resource:

POST /orders
GET /orders/{id}

Action on resource:

POST /orders/{id}/refund


API NAMING PRINCIPLES (THE STAFF VERSION)

  • Use nouns for resources

  • Use verbs for actions

  • Keep naming consistent across system

  • Prefer plural nouns: /users not /user

  • Avoid deep nesting (no more than 2 levels)

  • Think in terms of domain language

Great naming = great API usability.


VERSIONING (HOW REAL COMPANIES HANDLE IT)

Two main approaches:


1. URL Versioning

/v1/customers
/v2/customers

Pros:

  • extremely clear

  • avoids silent breakage

  • clients consciously upgrade

Stripe uses this.


2. Header Versioning

Accept: application/vnd.company.v2+json

Used for:

  • APIs that must remain visually clean

  • internal API evolution


Rules for API Versioning:

  1. Never break existing clients

  2. Add new fields → never remove

  3. Deprecation must be slow (6–24 months)

  4. Use feature flags for internal migrations

  5. Support two versions at minimum during transition

Backward compatibility = system stability.


IDIOMS OF EFFECTIVE API DESIGN

Every solid API follows these principles:


Principle 1 — Idempotency

Requests should be safe to retry — essential in distributed systems.

Idempotent Methods:

GET
PUT
DELETE

Non-idempotent:

POST
PATCH

But you can make POST idempotent by using an idempotency key:

Idempotency-Key: 9d12-abc-9981

Used by:

  • Stripe

  • PayPal

  • Uber

  • Shopify

Guarantees:

  • no duplicate charges

  • no repeated actions under retries

  • safe distributed retries

You MUST implement this for any financial, booking, or expensive workflow.


Principle 2 — Pagination Patterns

Three main forms:

1. Offset Pagination

?offset=0&limit=20

Simple but bad at scale.

2. Cursor Pagination

?cursor=xyz123

Best for:

  • infinite scroll

  • large datasets

  • high-offset performance

3. Time-based Pagination

Good for logs and analytics.


Principle 3 — Filtering & Sorting

Follow predictable patterns:

?status=active
?sort=created_at
?order=desc


Principle 4 — Error Handling (Stripe Standard)

Use:

{
"error": {
"type": "invalid_request",
"message": "Email is required",
"param": "email"
}
}

Never mix:

  • HTTP errors

  • business logic errors

HTTP Status Codes:

  • 200 → success

  • 400 → client error

  • 401 → unauthorized

  • 403 → forbidden

  • 404 → not found

  • 409 → conflict

  • 422 → validation error

  • 500 → server error


AUTHENTICATION (WHO ARE YOU?)

Authentication establishes user identity.

Main formats:


1. Session-Based Auth

Used by web portals, traditional apps.

Pros:

  • secure

  • server-controlled

  • easy to revoke

Cons:

  • not ideal for APIs

2. JWT Auth

Used for:

  • mobile

  • single-page apps

  • public APIs

Pros:

  • stateless

  • scalable

Cons:

  • difficult to revoke

  • must keep token small

  • must avoid storing sensitive data


3. OAuth 2.0

Used for:

  • Google login

  • GitHub login

  • LinkedIn auth

  • Third-party integrations

OAuth Flows:

  • Authorization Code (secure, recommended)

  • PKCE (mobile & SPA)

  • Client Credentials (server-to-server)

  • Refresh Tokens

This is must-know knowledge for modern backend engineering.


Token Rules:

  • short-lived access tokens

  • long-lived refresh tokens

  • store refresh tokens securely

  • use rotating tokens

  • invalidate on logout

Top-1% engineers NEVER:

  • store JWTs in localStorage

  • encode private data into JWT

  • use long-lived tokens


AUTHORIZATION (WHAT ARE YOU ALLOWED TO DO?)

Authentication answers: “Who are you?”

Authorization answers: “What can you do?”

Main Models:


Model 1 — Role-Based Access Control (RBAC)

admin
editor
viewer

Good for:

  • simple systems

Bad for:

  • large enterprises

Model 2 — Attribute-Based Access Control (ABAC)

if user.org_id == resource.org_id
if user.age > 18

Very flexible.

Used by:

  • AWS IAM

  • GCP IAM

  • internal enterprise systems


Model 3 — Policy-Based Access Control (PBAC)

Policies written in:

  • JSON

  • DSL

  • OPA/Rego

Used for:

  • complex, multi-tenant systems

  • financial platforms

  • healthcare systems

This is where STAFF engineers shine.


REQUEST LIFECYCLE ENGINEERING

Now we go deeper — into how a single request flows through your system.

A top engineer visualizes:

Knowing every step allows you to:

  • debug faster

  • optimize latency

  • locate bottlenecks

  • introduce security boundaries

  • design better architecture


MAKING APIS EVOLVE SAFELY

API evolution rules:

  1. Add fields → never remove

  2. New features → opt-in

  3. Add new endpoints → don’t break old ones

  4. APIs are contracts → honor them

  5. Support two versions during migration

  6. Provide strict deprecation timelines

Breaking an API breaks companies — this is taken extremely seriously in FAANG.


SECURING APIS (THE STAFF APPROACH)

Checklist:

  • input validation

  • rate limiting

  • schema validation

  • SQL injection protection

  • prevent over-fetching

  • prevent under-fetching

  • block verbose error messages

  • secure default CORS policies

  • reject malformed JSON

Bonus:

  • short TTL tokens

  • refresh token rotation

  • scope-based tokens

  • audit logs