# Consistent field naming convention

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

## Why it matters

Mixed casing in API response fields — `userId` alongside `created_at` in the same response object — forces every consumer to handle two naming conventions simultaneously. This is the classic sign of database column names leaking directly into the API layer without a serialization pass. It creates client-side bugs when consumers assume one convention and get the other, and it makes the API feel unfinished. iso-25010:2011 maintainability.modifiability is the direct impact: every client integration must special-case the inconsistency.

## Severity rationale

High because mixed field naming forces every API consumer to write defensive handling code, and the inconsistency compounds across every new endpoint added.

## Remediation

Pick one casing convention and enforce it with a serialization layer that transforms database field names before they leave the API. Add a transformer function in your handler files:

```ts
// Before -- mixed casing leaking from database:
{
  userId: row.user_id,
  created_at: row.created_at,  // forgot to transform
  firstName: row.first_name
}

// After -- consistent camelCase via transformer:
function toUserResponse(row) {
  return {
    userId: row.user_id,
    createdAt: row.created_at,
    firstName: row.first_name
  }
}
```

For larger codebases, use `camelcase-keys` or a serialization framework that enforces the convention globally.

## Detection

- **ID:** `field-naming`
- **Severity:** `high`
- **What to look for:** Examine response body field names across all endpoints. Check whether the API consistently uses one casing convention: `camelCase` (JavaScript convention), `snake_case` (Python/Ruby convention), or `PascalCase` (C#/.NET convention). Compare fields across at least 3 different endpoints. Also check that the chosen convention matches the ecosystem -- JavaScript/TypeScript APIs typically use camelCase, Python APIs typically use snake_case. Look for mixing within a single response (e.g., `{ userId: 1, created_at: "..." }`).
- **Pass criteria:** List all response field names across at least 3 endpoints and classify each as camelCase, snake_case, or PascalCase. All response field names across all endpoints must use one consistent casing convention. No mixing of camelCase and snake_case within or across responses. Do not pass when a single response mixes conventions (e.g., `userId` and `created_at` in the same object).
- **Fail criteria:** Mixed casing conventions found across endpoints (some return camelCase, others snake_case), or within a single response object. Field names from the database layer leak through without transformation (e.g., `{ userId: row.user_id, created_at: row.created_at }`). Quote the actual field names found in each convention.
- **Skip (N/A) when:** Fewer than 2 API endpoints return JSON response bodies. Also skip for gRPC (Protobuf enforces snake_case in `.proto` files and auto-converts per language).
- **Detail on fail:** Identify the inconsistency with examples (e.g., "User endpoint returns camelCase (`userId`, `firstName`) but order endpoint returns snake_case (`order_id`, `created_at`). 3 of 8 endpoints use snake_case while the rest use camelCase."). Max 500 chars.
- **Remediation:** Pick one casing convention and enforce it everywhere. Use a serialization layer to transform database field names before they reach the API response.

  ```ts
  // Before -- mixed casing leaking from database:
  {
    userId: row.user_id,
    created_at: row.created_at,  // forgot to transform
    firstName: row.first_name
  }

  // After -- consistent camelCase with a transformer:
  function toCamelCase(row) {
    return {
      userId: row.user_id,
      createdAt: row.created_at,
      firstName: row.first_name
    }
  }
  ```

  For larger APIs, use a library like `camelcase-keys` or a serialization framework that handles this automatically.

## External references

- iso-25010 maintainability.modifiability

Taxons: code-quality

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