Fundamentals/API Design

RESTful API Design

API Design

Visual Representation

Rendering diagram...

What is it?

📋 Think of it like a well-organized library:

A library has rules: books are organized by category, each has a unique code, you can CHECK OUT (read), RETURN, REQUEST new books, or REPORT damaged ones. Everyone follows the same system so anyone can find anything.

REST (Representational State Transfer) is a set of rules for designing APIs (menus for your server). Everything is a "resource" (like a book), each has a URL (unique address), and you use standard HTTP methods (actions) to interact with them.

It's not a technology — it's a STYLE of designing URLs and request patterns so that your API is intuitive, consistent, and easy for other developers to use.

💡 Simple Summary: REST = organize your API around resources (nouns) and use HTTP methods (verbs) consistently. URLs tell you WHAT, methods tell you WHAT TO DO.

How it works — Like you're watching it happen

Designing a Swiggy-like API:

Resources: restaurants, menu items, orders, users

ActionHTTP MethodURLWhat it does
List all restaurantsGET/restaurantsReturns list of restaurants
Get one restaurantGET/restaurants/42Returns restaurant #42's details
Create new orderPOST/ordersCreates an order, returns order ID
Update order statusPUT/orders/789Updates entire order #789
Cancel orderDELETE/orders/789Cancels/deletes order #789
Get restaurant reviewsGET/restaurants/42/reviewsSub-resource: reviews belonging to restaurant 42

The key insight: URLs are NOUNS (things), HTTP methods are VERBS (actions). NOT /getRestaurants or /deleteOrder — the method already tells you the action!

But wait — what if I need an action that doesn't fit CRUD? Like "search" or "checkout"?

Good question! REST purists say everything should be a resource. So "search" becomes: GET /restaurants?cuisine=italian&city=mumbai (query parameters on a collection). "Checkout" could be: POST /orders (creating the order IS the checkout). For truly action-oriented things, some APIs use: POST /orders/789/cancel or POST /payments/charge — slightly breaking REST but being pragmatic.

Why should you care? (Interview perspective)

  • 🎯 "Design the API for X" is asked in almost every system design interview
  • REST is the DEFAULT choice for public APIs — knowing best practices is expected
  • Bad API design = messy system. Good API design = clean, maintainable system
  • Shows you can think about developer experience and consistency
  • Key Things to Remember

  • Use nouns, not verbs — /users, /orders, /restaurants. NOT /getUsers, /createOrder, /deleteRestaurant. The HTTP method IS the verb.
  • Plural resource names — /users (not /user), /restaurants (not /restaurant). Consistent and intuitive.
  • HTTP methods match actions — GET (read, safe, cacheable), POST (create), PUT (full update), PATCH (partial update), DELETE (remove).
  • Status codes are responses — 200 (success), 201 (created), 204 (deleted, no content), 400 (bad request), 401 (not authenticated), 403 (not authorized), 404 (not found), 409 (conflict), 422 (validation error), 429 (rate limited), 500 (server error).
  • Nested resources — /users/123/orders (orders belonging to user 123). Don't nest more than 2 levels deep.
  • Filtering & sorting — Use query parameters: /restaurants?cuisine=chinese&sort=rating&order=desc. NOT /restaurants/chinese/sorted-by-rating.
  • Pagination — Always paginate lists: /users?page=1&limit=20 or cursor-based.
  • Consistent error format — Always return: { "error": { "code": "VALIDATION_ERROR", "message": "Email is required", "field": "email" } }.
  • Versioning — /api/v1/users. So you can evolve without breaking existing clients.
  • HATEOAS (optional) — Response includes links to related actions: { "user": {...}, "links": { "orders": "/users/123/orders" } }. Nice but rarely fully implemented.
  • Real Examples You Use Daily

    🐦 Twitter/X API — GET /2/tweets/:id (get tweet), POST /2/tweets (create tweet), DELETE /2/tweets/:id (delete tweet). Clean, resource-based, predictable.

    🛒 Stripe API — Considered gold-standard REST design. POST /v1/charges (create charge), GET /v1/customers/:id (get customer). Consistent naming, excellent error messages, proper status codes.

    📱 GitHub API — GET /repos/:owner/:repo (get repo), POST /repos/:owner/:repo/issues (create issue), PUT /repos/:owner/:repo/issues/:id (update issue). Nested resources done right.

    🚗 Uber API — GET /v1/estimates/price?start_lat=...&end_lat=... (price estimate). Query parameters for filtering, proper resource names.

    Common Mistakes in Interviews

    Using verbs in URLs — /getAllUsers, /deleteUser/123, /createPost. Use nouns + HTTP methods: GET /users, DELETE /users/123, POST /posts.

    Wrong status codes — Returning 200 for everything (even errors). Use 201 for creation, 404 for not found, 400 for validation errors. This isn't pedantic — clients parse these!

    No pagination — Returning 10,000 users in one response. Always paginate: /users?limit=20&offset=0.

    Inconsistent naming — /users vs /order vs /get-restaurants. Pick one convention (plural nouns, kebab-case) and stick to it.

    Not handling errors properly — Just returning "Error" string. Return structured error objects with code, message, and details so clients can programmatically handle them.

    🎯 Interview One-Liner

    "I design RESTful APIs around resources with plural nouns in URLs, standard HTTP methods for CRUD operations, proper status codes for every response, cursor-based pagination for lists, and consistent error formats — making the API intuitive enough that a developer can guess endpoints without reading docs."

    Interview Q&A

    Q: Design the API for an Instagram-like app.

    Resources: users, posts, comments, likes, stories. Key endpoints: POST /users (register), GET /users/:id (profile), GET /users/:id/posts (user's posts), POST /posts (upload with image), GET /feed (personalized feed), POST /posts/:id/comments (add comment), POST /posts/:id/likes (like), DELETE /posts/:id/likes (unlike). Pagination on all lists. Auth via Bearer token.

    Q: PUT vs PATCH — when to use each?

    PUT replaces the ENTIRE resource: PUT /users/123 sends the complete user object. If you omit a field, it gets cleared. PATCH updates only specified fields: PATCH /users/123 with { "name": "New Name" } changes just the name, everything else stays. Use PATCH for partial updates (more common in practice), PUT for full replacements.

    Q: How do you handle authentication in REST?

    Stateless authentication: every request includes credentials. Most common: Bearer token in Authorization header (Authorization: Bearer <jwt_token>). Server validates the JWT on every request without session state. For API keys: pass in header (X-API-Key: xxx) or query param. Never in URL path because URLs are logged. OAuth2 for third-party access.

    Q: How would you design a search endpoint?

    GET /restaurants?q=pizza&city=mumbai&min_rating=4&sort=distance&limit=20&cursor=abc123. Search is typically GET on the collection resource with query parameters for filters. For complex searches (full-text, geo, ML-ranked), some APIs use POST /search with a body (because query string gets too long). Both approaches are valid.

    Q: What makes the Stripe API so well-designed?

    Consistency: every resource follows the same pattern. Excellent errors: structured with type, code, message, and param. Idempotency: POST requests accept an Idempotency-Key header to prevent duplicate charges. Versioning: date-based API versions. Pagination: cursor-based. Expandable objects: ?expand[]=customer to inline related data. Documentation: interactive examples in every language.

    Quick Quiz

    1/5

    Which URL is properly RESTful for getting user 123's orders?