Flujo de nombres API

API Request & Response Case Converter

Mantén camelCase dentro de la aplicación y traduce JSON snake_case en la frontera request/response. Prueba ambas direcciones y copia un patrón con Fetch o Axios.

Respuesta: snake_case → camelCase · Solicitud: camelCase → snake_case

Dirección del límite API

API snake_case → aplicación camelCase
JSON camelCase de la aplicación
{
  "userProfile": {
    "firstName": "Ada",
    "createdAt": "2026-09-12"
  }
}
Claves renombradas: 3La conversión del payload se ejecuta localmente en tu navegador.

Generar código para el límite API

Elige un patrón de cliente HTTP JSON. El ejemplo convierte objetos salientes a snake_case y respuestas JSON entrantes a camelCase.

type JsonRecord = Record<string, unknown>

function isJsonObject(value: unknown): value is JsonRecord {
  if (value === null || typeof value !== "object" || Array.isArray(value)) {
    return false
  }
  return Object.getPrototypeOf(value) === Object.prototype
}

function splitPrefix(key: string) {
  const prefix = key.match(/^[_$]+/u)?.[0] ?? ""
  return { prefix, value: key.slice(prefix.length) }
}

function splitWords(value: string) {
  return value
    .replace(/([A-Z]+)([A-Z][a-z])/gu, "$1 $2")
    .replace(/([a-z0-9])([A-Z])/gu, "$1 $2")
    .split(/[^A-Za-z0-9]+/u)
    .filter(Boolean)
}

function toCamelKey(key: string) {
  const { prefix, value } = splitPrefix(key)
  const words = splitWords(value).map((word) => word.toLowerCase())
  const [firstWord, ...restWords] = words
  if (!firstWord) return key
  return prefix + firstWord + restWords
    .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
    .join("")
}

function toSnakeKey(key: string) {
  const { prefix, value } = splitPrefix(key)
  const words = splitWords(value).map((word) => word.toLowerCase())
  return words.length ? prefix + words.join("_") : key
}

function mapJsonKeys(
  value: unknown,
  convertKey: (key: string) => string,
): unknown {
  if (Array.isArray(value)) {
    return value.map((item) => mapJsonKeys(item, convertKey))
  }

  if (!isJsonObject(value)) {
    return value
  }

  const output: JsonRecord = {}
  for (const [key, child] of Object.entries(value)) {
    const nextKey = convertKey(key)
    if (Object.hasOwn(output, nextKey)) {
      throw new Error(`Key collision after case conversion: ${nextKey}`)
    }
    output[nextKey] = mapJsonKeys(child, convertKey)
  }
  return output
}

export function keysToCamel(value: unknown) {
  return mapJsonKeys(value, toCamelKey)
}

export function keysToSnake(value: unknown) {
  return mapJsonKeys(value, toSnakeKey)
}

export async function apiJson<T>(
  url: string,
  options: { method?: string; body?: unknown } = {},
): Promise<T> {
  const response = await fetch(url, {
    method: options.method ?? (options.body === undefined ? "GET" : "POST"),
    headers: { "content-type": "application/json" },
    body:
      options.body === undefined
        ? undefined
        : JSON.stringify(keysToSnake(options.body)),
  })

  if (!response.ok) {
    throw new Error(`API request failed: ${response.status}`)
  }

  const wireData: unknown = await response.json()
  return keysToCamel(wireData) as T
}

Este límite está pensado para payloads JSON. Mantén FormData, Blob, streams, archivos y otros cuerpos no JSON fuera del mapper.

Centraliza la conversión en el límite API

Componentes, hooks, stores y código de dominio mantienen una convención interna mientras el contrato JSON externo puede usar otra.

1. Normaliza respuestas entrantes

Después de analizar el JSON del servidor, convierte recursivamente las claves snake_case a camelCase antes de usarlas en la app.

2. Normaliza solicitudes salientes

Antes de serializar JSON, convierte las claves camelCase de la app al snake_case esperado por la API.

3. Deja fuera los cuerpos no JSON

No pases FormData, Blob, streams, archivos o instancias de clase arbitrarias por un mapper de claves JSON.

¿Necesitas stop paths, exclusiones regex, diff o archivos JSON locales?

Usa JSON Key Case Converter para reglas avanzadas de objetos y aplica la misma política en tu código.

Abrir JSON Key Case Converter

Guías de implementación API

Elige la guía del cliente HTTP, query function, serializador o capa de modelos que uses.