Skip to content
API Design Learn/Querying, Errors & Contracts
Browsing as a guest. Sign in to save your progress and earn XP as you complete chapters.

Designing Request & Response Schemas

7 min read

You'll learn to

  • -Design DTOs (data transfer objects) deliberately, separate from internal database models
  • -Choose field types, naming conventions, and enum representations that stay stable as the underlying implementation changes

The shape of a request or response body is itself part of the API's contract, just as much as the URL and method - and the most common mistake here is serializing an internal database model directly as the API response, coupling the public contract to implementation details that should be free to change.

DTOs: A Deliberate Boundary

A DTO (Data Transfer Object) is the schema an API actually exposes - distinct from whatever internal representation (a database row, an ORM model) the server happens to use. Serializing a database model directly is tempting because it requires no extra code, but it means every internal column becomes part of the public contract: renaming an internal column, splitting a table, or adding an internal-only audit field all risk silently changing or leaking through the public API.

A deliberate response DTO, not a raw database row
// Internal DB row might have: id, email, password_hash, created_at,
// updated_at, internal_risk_score, deleted_at, legacy_migration_flag...

// The DTO exposes only what the API actually promises to clients:
{
  "id": 42,
  "email": "ada@example.com",
  "display_name": "Ada Lovelace",
  "created_at": "2026-01-15T10:30:00Z"
}

Field Types and Naming

  • -Use a consistent casing convention across every field - snake_case or camelCase, either is fine, but mixing them within one API forces every client to remember which fields use which style.
  • -Represent timestamps in one consistent, unambiguous format (ISO 8601 with an explicit timezone/UTC marker) rather than a raw epoch integer in some places and a formatted string in others.
  • -Use enums for closed, known sets of values (`"status": "shipped"`) rather than free-form strings or magic numbers a client has to look up in documentation.
  • -Represent money as an integer in the smallest currency unit (cents) or a proper decimal type - never as a floating-point number, for exactly the precision reasons covered in LLD Fundamentals' money-modeling chapter.

Nullable vs. Optional vs. Absent

These three are genuinely different and worth being precise about: a field that is always present but can be `null` ("this user has no middle name") is different from a field that might be entirely absent from the response ("this field is only included for premium accounts"), which is different again from a field that is optional on requests but always present on responses (a default gets filled in server-side). Conflating these leads to client code that can't tell "this value is empty" from "this field doesn't apply here" from "I forgot to check if this key exists."

A DTO also gives you a natural place to version a response shape independently of the underlying storage schema - changing an internal database column never has to mean a breaking API change, and changing the DTO never has to mean a database migration.

Interview Signal

A teammate proposes returning the ORM model's `.to_dict()` directly as the API response, to save time. What would you say?

Weak Answer

"That's fine for now, we can always change it later if it becomes a problem."

Strong Answer

"I'd push back before it ships, not after - once clients depend on whatever fields the ORM happens to expose, every internal change (renaming a column, adding an internal-only field, changing the ORM version) becomes a potential breaking change to the public API. A deliberate DTO decouples the two, so I can refactor the database freely as long as the DTO's output stays the same - that boundary gets much more expensive to introduce after real clients are already depending on the raw model shape."

Check Yourself1 / 3

What problem does serializing an internal database model directly as an API response create?

Ready to Build This?

Design Request & Response in the API Design Lab's REST Foundations act.

ScaleDojo Logo
Initializing ScaleDojo