Workflow de nommage API
API Request & Response Case Converter
Conservez camelCase dans l’application et traduisez le JSON snake_case à la frontière request/response. Testez les deux directions et copiez un modèle Fetch ou Axios.
Réponse : snake_case → camelCase · Requête : camelCase → snake_case
Direction de la frontière API
{
"userProfile": {
"firstName": "Ada",
"createdAt": "2026-09-12"
}
}Générer le code de frontière API
Choisissez un modèle de client HTTP JSON. L’exemple généré convertit les objets sortants en snake_case et les réponses JSON entrantes en 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
}Cette frontière est conçue pour les payloads JSON. Gardez FormData, Blob, streams, fichiers et autres corps non JSON hors de ce mapper.
Centraliser la conversion à la frontière API
Les composants, hooks, stores et modèles gardent une convention interne tandis que le contrat JSON externe peut en utiliser une autre.
1. Normaliser les réponses entrantes
Après l’analyse du JSON serveur, convertissez récursivement les clés snake_case en camelCase avant leur utilisation dans l’application.
2. Normaliser les requêtes sortantes
Avant la sérialisation JSON, convertissez les clés camelCase de l’application vers le snake_case attendu par l’API.
3. Exclure les corps non JSON
Ne passez pas FormData, Blob, streams, fichiers ou instances de classe arbitraires dans un mapper de clés JSON.
Besoin de stop paths, exclusions regex, diff ou fichiers JSON locaux ?
Utilisez JSON Key Case Converter pour les règles objet avancées, puis appliquez la même politique dans votre code.
Ouvrir JSON Key Case ConverterGuides d’implémentation API
Choisissez un guide adapté au client HTTP, à la query function, au sérialiseur ou à la couche de modèles.
Fetch API
Encapsulez les requêtes et réponses JSON sans toucher aux corps non JSON.
Axios
Utilisez une instance Axios dédiée avec des interceptors request/response.
TanStack Query
Placez la conversion dans les fonctions query/mutation partagées, pas dans les composants.
Jackson
Appliquez des stratégies de nommage à la sérialisation Java.
Pydantic
Utilisez les alias de modèles pour séparer champs Python et JSON externe.
Dictionnaires Python
Convertissez récursivement les clés dict/list lorsqu’il n’y a pas de couche modèle.