Construindo Clientes de API Type-Safe com OpenAPI e TypeScript
Todo desenvolvedor frontend já passou por isso: você busca dados de uma API, acessa um campo que deveria existir e recebe undefined em tempo de execução. O TypeScript deveria prevenir isso. O problema é que response.json() retorna any, então o compilador não tem nada para verificar. Este guia mostra como corrigir isso adequadamente—gerando tipos diretamente da sua especificação OpenAPI e usando-os para construir clientes REST type-safe em TypeScript.
Principais Conclusões
- Interfaces TypeScript escritas manualmente se desalinham da sua API real, criando uma falsa sensação de segurança que leva a erros em tempo de execução.
- A geração de código OpenAPI produz tipos diretamente da sua especificação de API, mantendo seu frontend e backend sincronizados.
- Use
openapi-typescriptcomopenapi-fetchpara uma configuração leve baseada em fetch, ou Orval para hooks TanStack Query gerados e SDKs de cliente completos. - Automatize a geração de tipos no CI ou nos seus scripts de build para que os tipos nunca fiquem desatualizados.
- Combine tipos gerados com um validador em tempo de execução como Zod para endpoints críticos onde a segurança em tempo de compilação sozinha não é suficiente.
Por Que a Tipagem Manual Falha
A correção ingênua é escrever interfaces manualmente:
// ❌ Compila bem, mas o TypeScript está apenas confiando em você
const data = (await response.json()) as User
Isso fornece autocomplete, mas se torna uma mentira no momento em que o backend muda. Seus tipos se desalinham da realidade, e você volta às surpresas em tempo de execução.
A melhor abordagem: gerar tipos a partir da fonte da verdade—sua especificação OpenAPI.
O Fluxo de Trabalho de Geração de Código OpenAPI TypeScript
O fluxo de trabalho típico se parece com isto:
- Comece com uma especificação OpenAPI (YAML ou JSON, hospedada ou local)
- Execute um gerador para produzir tipos TypeScript ou um cliente completo
- Importe esses tipos no código da sua aplicação
Isso mantém seu frontend sincronizado com o backend automaticamente. Quando a especificação muda, você regenera e o TypeScript informa exatamente o que quebrou.
Escolhendo Sua Abordagem: Apenas Tipos vs. SDK de Cliente Completo
Existem duas estratégias principais para geração de código OpenAPI TypeScript, e a escolha certa depende do seu projeto.
| Abordagem | Ferramentas | Melhor Para |
|---|---|---|
| Gerar tipos, trazer seu próprio fetch | openapi-typescript + openapi-fetch | Projetos leves baseados em fetch |
| Gerar um SDK de cliente completo | Orval, OpenAPI Generator | Equipes que desejam hooks e clientes prontos |
Geração apenas de tipos mantém seu bundle pequeno e permite que você controle a camada HTTP. Geração completa de SDK economiza tempo de configuração, mas adiciona mais código gerado para manter.
OpenAPI 3.0 vs 3.1: A maioria das ferramentas suporta bem o OpenAPI 3.0. O suporte ao OpenAPI 3.1 varia—verifique a documentação do seu gerador antes de assumir compatibilidade completa.
Discover how at OpenReplay.com.
Abordagem 1: openapi-typescript com openapi-fetch
Este é o caminho com runtime mínimo. Gere tipos da sua especificação, depois use openapi-fetch como um wrapper fino e totalmente tipado em torno da API Fetch nativa.
npx openapi-typescript ./openapi.yaml -o ./src/api/types.ts
npm install openapi-fetch
import createClient from "openapi-fetch"
import type { paths } from "./api/types"
const client = createClient<paths>({ baseUrl: "https://api.example.com" })
// Path, parâmetros e resposta são todos verificados por tipo
const { data, error } = await client.GET("/users/{id}", {
params: { path: { id: 123 } },
})
// TypeScript sabe exatamente como `data` se parece
console.log(data?.email)
Erros de digitação em paths, tipos de parâmetros incorretos e formatos de resposta incompatíveis se tornam erros de compilação. Overhead mínimo em runtime e apenas uma pequena dependência de runtime (openapi-fetch).
Abordagem 2: Orval para Geração Completa de Cliente
O Orval gera funções de API tipadas e—criticamente—pode gerar hooks do TanStack Query diretamente da sua especificação. Isso é útil quando você quer que a lógica de busca de dados seja tratada para você.
npm install orval --save-dev
Configure orval.config.ts para apontar para sua especificação e escolha um modo de saída (fetch, axios ou react-query). O Orval então gera funções como useGetUsers() com segurança de tipo completa incorporada.
Esta abordagem adiciona mais código gerado, mas para APIs maiores reduz significativamente o boilerplate.
Mantendo os Tipos Sincronizados
O valor real da geração de cliente OpenAPI TypeScript só se mantém se você regenerar consistentemente. Adicione a etapa de geração ao seu fluxo de trabalho de desenvolvimento:
{
"scripts": {
"generate:api": "openapi-typescript ./openapi.yaml -o ./src/api/types.ts"
}
}
Execute no CI, ou observe mudanças na especificação localmente. Algumas equipes commitam o arquivo gerado; outras regeneram a cada build. Qualquer uma funciona—apenas torne automático.
O Que Você Ainda Precisa Lidar
Tipos gerados geralmente fornecem segurança apenas em tempo de compilação. A validação em tempo de execução requer ferramentas adicionais como Zod ou plugins de gerador. Para endpoints críticos, combine seus tipos gerados com Zod para validar respostas em tempo de execução e capturar bugs do backend antes que eles cheguem à sua UI.
Conclusão
A geração de código OpenAPI TypeScript é uma das melhorias de maior impacto que você pode fazer em uma base de código frontend. Escolha openapi-typescript com openapi-fetch para uma configuração leve, ou Orval se você quiser hooks de query gerados. De qualquer forma, você para de escrever tipos manualmente, para de adivinhar formatos de resposta e deixa o compilador fazer o trabalho para o qual foi projetado.
Perguntas Frequentes
Sim. O openapi-typescript suporta especificações OpenAPI 3.0 e 3.1, embora alguns recursos de schema possam exigir testes com seu gerador e especificação específicos. Sempre verifique a saída gerada após atualizar a versão da sua especificação.
Absolutamente. Tipos gerados fornecem segurança em tempo de compilação, enquanto o Zod valida dados em tempo de execução. Você pode definir schemas Zod que espelham seus tipos gerados e analisar respostas de API através deles. Isso captura casos onde o backend retorna dados inesperados que o compilador não pode detectar.
Ambas as abordagens funcionam. Commitar arquivos gerados torna os builds mais rápidos e permite revisar mudanças de tipo em pull requests. Regenerar a cada build garante que os tipos estejam sempre atualizados, mas adiciona uma dependência na etapa de build. Escolha o que melhor se adequa ao fluxo de trabalho da sua equipe e configuração de CI.
O Orval é construído especificamente para TypeScript e gera hooks TanStack Query, clientes Axios ou funções fetch com configuração mínima. O OpenAPI Generator suporta muitas linguagens, mas produz saída TypeScript mais verbosa. Para equipes focadas em frontend, o Orval tipicamente requer menos customização para obter código limpo e idiomático.
Complete picture for complete understanding
Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.
Check our GitHub repo and join the thousands of developers in our community.