O que é OpenAPI?
OpenAPI é uma descrição de uma API HTTP legível por máquina. Escrito em YAML ou JSON, um único documento lista cada endpoint, seus parâmetros, corpos de requisição, respostas e autenticação. Por ser estruturado, diversas ferramentas podem consumi-lo: UIs de documentação, clientes tipados, server stubs, mocks e validadores.
Swagger era o nome original; agora ele se refere ao conjunto de ferramentas, especialmente o Swagger UI. A especificação em si é o OpenAPI, que se tornou o padrão de fato para descrever APIs REST. Se você já utilizou uma referência de API interativa com um botão “Try it out”, você utilizou OpenAPI.
A estrutura de um documento
Um documento OpenAPI possui algumas seções de nível superior.
# openapi.yaml
openapi: 3.1.0
info:
title: Posts API
version: 1.0.0
servers:
- url: https://api.example.com/v1
paths:
/posts:
get:
summary: List posts
responses:
"200":
description: A list of posts
- openapi declara a versão da especificação.
- info contém o título, a versão e a descrição.
- servers lista as URLs base.
- paths descreve cada endpoint e suas operações.
- components contém elementos reutilizáveis.
Caminhos e operações
Cada caminho mapeia para um ou mais métodos HTTP, e cada operação descreve suas entradas e saídas.
# paths.yaml
paths:
/posts/{id}:
get:
summary: Get a post
parameters:
- name: id
in: path
required: true
schema: { type: string }
responses:
"200":
description: The post
content:
application/json:
schema:
$ref: "#/components/schemas/Post"
"404":
description: Not found
Os parâmetros podem estar no path, query, header ou cookie. Os corpos de requisição são declarados com um tipo de conteúdo e um schema, e cada resposta deve listar seus códigos de status e formatos. Bons resumos e descrições transformam a especificação em uma documentação útil por si só.
Componentes e referências
A reutilização é o que mantém uma especificação sustentável. Defina as formas (shapes) apenas uma vez e referencie-as com $ref.
# components.yaml
components:
schemas:
Post:
type: object
required: [id, title]
properties:
id: { type: string }
title: { type: string }
publishedAt: { type: string, format: date-time }
parameters:
Limit:
name: limit
in: query
schema: { type: integer, minimum: 1, maximum: 100 }
responses:
NotFound:
description: Resource not found
Uma alteração no schema Post atualiza todas as operações que o referenciam, o que evita a divergência que costuma ocorrer em definições duplicadas.
Segurança
A autenticação é declarada uma única vez e aplicada por operação.
# security.yaml
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
security:
- bearerAuth: []
As ferramentas podem, então, enviar as credenciais corretas na UI da documentação, e os clientes gerados podem aceitar um parâmetro de token.
Documentação e geração de código
A especificação impulsiona o ferramental:
- Swagger UI renderiza uma referência interativa onde os usuários podem testar requisições.
- Redoc renderiza uma página de documentação limpa, dividida em três painéis.
- openapi-generator produz clientes e stubs de servidor em diversas linguagens.
- openapi-typescript gera tipos TypeScript a partir da especificação.
- Spectral faz o lint da especificação para garantir consistência e estilo.
- Mock servers servem respostas de exemplo para que o trabalho de front-end possa começar antes que o backend esteja pronto.
# docs.sh
npx @redocly/cli preview-docs openapi.yaml
npx openapi-typescript openapi.yaml -o src/api-types.ts
Como tudo deriva de um único arquivo, a documentação, os clientes e os tipos permanecem consistentes.
Spec-first versus code-first
Existem dois fluxos de trabalho:
- Spec-first: desenhe o contrato antes de implementar. Ideal para APIs públicas, múltiplos consumidores e trabalho paralelo entre front-end e back-end. A especificação é a fonte da verdade.
- Code-first: anote as rotas e tipos e, em seguida, gere a especificação. Mantém a especificação próxima da implementação e evita a duplicação em frameworks tipados.
Ambos funcionam. O ponto de falha em qualquer um dos casos é manter a documentação manualmente em um local separado, onde ela se torna obsoleta silenciosamente.
Validação e testes de contrato
Um documento OpenAPI pode ser aplicado, e não apenas lido.
- Validação de requisições: o middleware rejeita requisições que não condizem com a especificação, permitindo que os handlers confiem em seus inputs.
- Validação de respostas: os testes asseguram que as respostas correspondam aos seus schemas declarados.
- Testes de contrato: clientes e servidores validam-se contra a mesma especificação, detectando breaking changes precocemente.
É aqui que a especificação prova seu valor: ela se torna um contrato executável em vez de apenas documentação.
Melhores práticas
- Mantenha uma spec por API e trate-a como a fonte da verdade.
- Reutilize schemas, parâmetros e respostas com
$ref. - Escreva sumários e descrições claras; eles se tornarão a documentação.
- Documente cada status code que uma operação pode retornar.
- Valide requisições e respostas com base na spec.
- Gere clients, types e documentação em vez de escrevê-los manualmente.
- Faça o lint da spec e revise as alterações em pull requests.
Erros comuns
- Manter a documentação manualmente e de forma separada da spec.
- Duplicar schemas inline até que eles se tornem divergentes.
- Esquecer as respostas de erro, impedindo que os clientes tratem falhas.
- Usar nomes e descrições vagas que não ajudam os consumidores.
- Permitir que a spec se distancie da implementação.
- Pular a validação e perder o principal benefício do contrato.
Próximos passos
O OpenAPI transforma uma API em um contrato que tanto ferramentas quanto pessoas podem utilizar. Construa-a com base em um design REST sólido, evolua-a cuidadosamente com Versionamento de API e alinhe-a com o guia HTTP. Em seguida, descreva um endpoint que você já possua e gere um client a partir dele.