# Response objects are typed

- **Pattern:** `ab-000361` (`api-design.contract-quality.response-types`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000361
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000361)

## Why it matters

Handlers that return ad-hoc inline objects — `{ id: user.id, name: user.name, role: user.role }` — with no shared type definition silently expose database columns that were never intended for the API surface. Without explicit response types, a refactor that renames a database column silently changes the API contract, and TypeScript's type system provides zero protection. iso-25010:2011 maintainability.modifiability and compatibility.interoperability both degrade: the API shape can change with any database migration and no tooling catches it.

## Severity rationale

High because untyped responses expose accidental data leakage paths and remove TypeScript's protection against API shape changes caused by database refactors.

## Remediation

Define explicit TypeScript interfaces for every API response shape and use a dedicated serialization function to enforce them:

```ts
interface UserResponse {
  id: string
  name: string
  email: string
  isActive: boolean
  createdAt: string
}

function toUserResponse(user: DbUser): UserResponse {
  return {
    id: user.id,
    name: user.name,
    email: user.email,
    isActive: user.is_active,
    createdAt: user.created_at.toISOString(),
  }
}
```

The serialization function is the explicit allowlist of what leaves the database layer. Any new field must be added deliberately, not by accident.

## Detection

- **ID:** `response-types`
- **Severity:** `high`
- **What to look for:** Check whether response objects have explicit type definitions. For TypeScript: look for interface/type declarations for API responses, or Zod schemas used for both validation and response typing. For Python: Pydantic response models, TypedDict, or dataclass-based responses. For Go: struct types for JSON marshaling. Look for anti-patterns: returning raw database rows without a DTO layer, using `any` or untyped objects for responses, constructing response objects inline with no type safety.
- **Pass criteria:** API response objects have explicit type definitions (TypeScript interfaces, Pydantic models, Go structs, etc.). Response shapes are predictable and documented through types. Handlers return typed objects, not raw database rows or untyped dictionaries. Enumerate all handler files and classify each response as typed or untyped. At least 80% of endpoints must have explicitly typed responses.
- **Fail criteria:** Response objects are constructed ad-hoc with no type definitions. Handlers return `any`-typed objects, spread raw database rows into responses, or construct response objects inline without a shared type. Should not pass when handlers use `as any` type assertions to bypass type checking on responses.
- **Skip (N/A) when:** The API is written in plain JavaScript with no TypeScript, and no type annotation system is used. Also skip for languages where typing is optional and not adopted in the project.
- **Detail on fail:** Describe what's missing (e.g., "No TypeScript interfaces for any response objects. Handlers return inline objects like `{ id: user.id, name: user.name }` with no shared type. 8 of 12 endpoints return untyped responses."). Max 500 chars.
- **Remediation:** Define explicit types for every API response shape:

  ```ts
  // Define response types:
  interface UserResponse {
    id: string
    name: string
    email: string
    isActive: boolean
    createdAt: string
  }

  // Use in handler -- type safety prevents accidental field exposure:
  function toUserResponse(user: DbUser): UserResponse {
    return {
      id: user.id,
      name: user.name,
      email: user.email,
      isActive: user.is_active,
      createdAt: user.created_at.toISOString(),
    }
  }
  ```

## External references

- iso-25010 maintainability.modifiability
- iso-25010 compatibility.interoperability

Taxons: code-quality

HTML version: https://auditbuffet.com/patterns/ab-000361
