Nouns Before Verbs
Before any endpoint exists, decide what things exist. Resource modeling picks the nouns — and every later decision (URLs, caching, authorization, pagination) inherits from it.
RideShare domain objects → API resources
Trip → /trips/{tripId} (created, transitions state)
Driver → /drivers/{driverId} (public profile subset)
Rider → /riders/{riderId}
Payment → /trips/{tripId}/payment (child of trip lifecycle)
FareEstimate → /fare-estimates (ephemeral computed resource)
NOT modeled as resources:
"bookRide" action → becomes POST /rides (creation of a Ride resource)
The last line is the classic judgment call: verbs in URLs usually signal a missing resource. “Send email” is POST /emails — the send is creation.
Modeling Tests
A resource model is healthy when:
- CRUD maps naturally — most resources support create/get/list/update without contortion.
- Identifiers are stable and opaque —
trip_8f3k2, never emails or composite meaning-laden strings. - Ownership is unambiguous — every resource has exactly one parent path to it.
- Lifecycle is expressible — stateful entities expose state, not state-changing verb endpoints.
Relationships: Nesting vs Referencing
NESTED (ownership hierarchy)
GET /drivers/{id}/trips ← trips belonging to driver
FLAT + FILTER (many-to-many, cross-cutting queries)
GET /trips?driver_id={id}&status=completed
rule: nest ONE level for true ownership;
deeper nesting (a/b/c/d) collapses into filters
Nesting expresses containment (“these trips are his”); filtering expresses querying (“show me trips where…”). Mixing them up produces unusable deep paths and duplicated endpoints.
Computed and Ephemeral Resources
Not every resource is stored — some are calculated on demand:
POST /fare-estimates body: origin, destination, ride_type
201 → { estimate_id, price_range, expiry_seconds }
modeled as a resource because:
- it has identity (referenced if rider proceeds)
- it expires (lifecycle)
- creating it may be billable/rate-limited like any write
The Schema Behind Resources
Each resource needs its public field set decided deliberately:
Trip (public view):
id, status, driver_summary{...}, pickup, dropoff,
fare{}, created_at, eta_minutes?
hidden by design: internal routing data, PSP tokens, cost basis
public API = a PROJECTION of internal models, not a dump
Interview Framing
“Define your data model and APIs” beats in interviews follow a rhythm: list 4–6 nouns with ids, mark each as stored/computed/ephemeral, show one nested ownership route plus one filter-based query route, then define fields for the two most important resources. That’s five minutes producing the skeleton every scaling discussion hangs on.
Premium Content
Unlock Resource Modeling and all premium lessons with a subscription.
From ₹199.99/year — See plans