Question 11 · Section 6

What is RESTful API design?

4. Return the correct status codes:

Language versions: English Russian Ukrainian

Junior Level

RESTful design is a set of rules for creating APIs that follow REST principles.

Basic rules:

  1. Use nouns for resources:
    • GET /users — get users
    • GET /getUsers — no verbs needed
  2. Use the correct HTTP methods:
    • GET — read
    • POST — create
    • PUT — full update
    • PATCH — partial update
    • DELETE — delete
  3. Use plural forms:
    • Plural form is recommended — it’s the most common convention.
    • But singular is acceptable if the team agrees on it.
    • /users, /orders, /products
    • /user, /order, /product
  4. Return the correct status codes:
    • 200 — success
    • 201 — created
    • 400 — client error
    • 404 — not found
    • 500 — server error

Example of a well-designed RESTful API:

GET    /users          — list of users
GET    /users/1        — user with ID 1
POST   /users          — create a user
PUT    /users/1        — fully update the user
PATCH  /users/1        — partially update the user
DELETE /users/1        — delete the user

Middle Level

Richardson Maturity Model

  • Level 0 (The Swamp of POX): HTTP as transport (RPC over HTTP)
  • Level 1 (Resources): Use of resources (individual URIs)
  • Level 2 (HTTP Verbs & Statuses): HTTP methods and status codes. This is the industry “gold standard”
  • Level 3 (HATEOAS): Hypermedia. The most expensive level — overhead of building a link graph and increasing JSON by 30-50%

Design-First vs Code-First

  1. Design-First (OpenAPI/Swagger YAML): Contract first, then code is generated
    • Pro: Parallel frontend and backend development. Guaranteed documentation compliance
    • Con: Complexity of maintaining YAML with frequent changes
  2. Code-First (SpringDoc/Swagger Annotations): Code first, documentation generated from annotations
    • Pro: Fast iteration
    • Con: Documentation often “lags” behind the code

Performance

  • Idempotency in design: Design your API so that PUT and DELETE are safe to retry. This enables aggressive retry policies at the Service Mesh level (Istio)
  • Payload Optimization: In Highload systems, REST-over-Protobuf or MessagePack is used instead of JSON
  • Negative Caching: Negative Caching is caching error responses. If an attacker scans the API with non-existent requests, the CDN returns a cached 404 instead of loading the backend. 1 second is a compromise: protection from brute-force without the risk of a legitimate client not seeing a newly created resource for too long. Configure the CDN so that 404 and 403 responses are cached for a short time (1 sec).

N+1 Problem in REST

Unlike GraphQL, REST suffers from excessive requests.

  • Solution: embed or include parameter (/orders?include=items)

HTTP Method Tunneling

If the client doesn’t support PATCH, use POST with the X-HTTP-Method-Override: PATCH header.


Senior Level

When RESTful design is excessive

  1. Internal microservices — gRPC/Thrift is better
  2. Real-time streaming — WebSocket/gRPC
  3. Simple RPC calls without CRUD semantics

DispatcherServlet and HandlerMapping

In Spring MVC, the implementation of RESTful design is handled by DispatcherServlet, which uses HandlerMapping to map the combination of HTTP Method + URI to a specific controller method.

Maturity levels and their cost

  • Level 2: Here it’s important not only to use POST, but also to return 201 Created with a Location header
  • Level 3: The main complexity is the overhead of building a link graph and increasing JSON size

Diagnostics and Monitoring

  • Correlation ID: It’s recommended to include X-Request-ID (or X-Correlation-ID) in every response. This ID is passed through all microservices in the call chain, allowing all logs of a single request to be assembled in ELK.
  • Problem Details (RFC 9457): Spring Boot 3+ supports this via ProblemDetail. Makes errors machine-readable
  • Latency Monitoring: Track latency histograms (P99) not per endpoint, but broken down by method (GET vs POST), since their load profiles are fundamentally different

Edge Cases

  • Trailing Slash: /users/ and /users — two different resources. Configure StrictTrailingSlashPatternMatch in Spring
  • API Discovery: A well-designed API allows calling OPTIONS /users and getting a list of available methods

Interview Cheat Sheet

Must know:

  • RESTful design = nouns in URI + correct HTTP methods + plural form + status codes
  • Richardson Maturity Model: Level 2 (HTTP Verbs + Status Codes) — industry gold standard
  • Design-First (OpenAPI/Swagger) vs Code-First (SpringDoc) — Design-First guarantees parallel development
  • HATEOAS (Level 3) — most expensive level, 30-50% JSON overhead, not needed for internal microservices
  • N+1 Problem in REST is solved via embed/include parameters (/orders?include=items)
  • Negative Caching — caching 404/403 responses to protect against brute-force scanning
  • gRPC is better for internal microservices, WebSockets for real-time

Common follow-up questions:

  • Why plural in URIs? — /users represents a collection, /users/1 — an element of the collection
  • When is Design-First better than Code-First? — When frontend and backend are developed in parallel
  • What is API Discovery? — Calling OPTIONS /resource returns a list of available methods
  • Why is HATEOAS rarely used? — Overhead of link generation, 30-50% JSON increase, not needed for a single team

Red flags (DO NOT say):

  • “Verbs in URLs are fine for REST” — URI should be a noun, action = HTTP method
  • “HATEOAS is mandatory in every project” — excessive for internal APIs and mobile apps
  • “REST is suitable for everything” — gRPC/WebSockets are better for streaming and RPC
  • “Code-First is always better” — documentation often lags behind code, Design-First provides a contract

Related topics:

  • [[What is REST]]
  • [[How to properly name REST endpoints]]
  • [[Should you use verbs in URL]]
  • [[What is HATEOAS]]
  • [[What HTTP status codes do you know]]