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:
/usersnot/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:
-
Never break existing clients
-
Add new fields → never remove
-
Deprecation must be slow (6–24 months)
-
Use feature flags for internal migrations
-
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:
-
Add fields → never remove
-
New features → opt-in
-
Add new endpoints → don’t break old ones
-
APIs are contracts → honor them
-
Support two versions during migration
-
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