A Melhor Configuração de Linter OpenAPI para Design Consistente de API em 2026

Pense na etapa anterior: A comparação de opções de linter OpenAPI (Spectral, Redocly, Vacuum) e a configuração de um ambiente consistente em editor, pre-commit e CI para um design de API testado por contrato.

INEZA Felin-Michel

INEZA Felin-Michel

16 junho 2026

A Melhor Configuração de Linter OpenAPI para Design Consistente de API em 2026

Apidog para empresas

Implantação local

SSO & RBAC

Conforme SOC 2

Explorar Apidog Enterprise

Dois engenheiros da mesma equipe implementam dois endpoints na mesma semana. Um retorna created_at, o outro retorna createdAt. Um pagina com ?page=2, o outro com ?offset=20. Um coloca erros em um objeto error de nível superior, o outro insere uma string message. Ambos passam na revisão de código, porque os revisores estão lendo a lógica, não a nomenclatura. Seis meses depois, sua superfície de API parece ter sido escrita por cinco empresas diferentes, e cada integração de cliente precisa de um caso especial.

Um linter OpenAPI existe para pegar essa inconsistência antes que ela seja implementada. Ele lê seu documento OpenAPI, o executa contra um conjunto de regras (operações precisam de descrições, schemas precisam de exemplos, nomes de propriedades seguem uma convenção de maiúsculas/minúsculas, cada resposta declara um tipo de mídia), e falha na build quando uma regra é quebrada. É a mesma ideia do ESLint para JavaScript ou RuboCop para Ruby, apontado para o seu contrato de API em vez do seu código de aplicação. Se você já desejou que a revisão de design de API pudesse ser automatizada da mesma forma que a formatação de código, é exatamente isso que um linter faz.

💡
Se você projeta e testa suas APIs no Apidog, você também obtém verificações de consistência durante o design, além de uma CLI que controla o resto do seu pipeline, então o linter não é a única coisa entre uma especificação desleixada e a produção. (Baixe o Apidog se quiser acompanhar os exemplos do lado do design.)
botão

O que um linter OpenAPI realmente verifica

Um linter opera no arquivo de especificação, não em um servidor em execução. Aponte-o para openapi.yaml e ele percorre cada caminho, operação, parâmetro, esquema e resposta, aplicando as regras uma por uma. As regras se enquadram em algumas categorias.

Validade. Este é mesmo um documento OpenAPI legal? Todos os $ref se resolvem? As palavras-chave necessárias estão presentes? Isso se sobrepõe à validação de esquema simples, e a maioria dos linters faz isso como base antes de qualquer outra coisa.

Completude. Cada operação tem um operationId, um resumo e uma descrição? Cada parâmetro se explica? Cada esquema carrega um example? Estas são as regras que tornam a documentação e os SDKs gerados realmente utilizáveis, e são as que os humanos mais esquecem.

Consistência. Este é o verdadeiro prêmio. Nomes de propriedades usam uma convenção de maiúsculas/minúsculas. Segmentos de caminho são substantivos no plural. Respostas de erro compartilham um mesmo formato. Cada resposta 2xx declara application/json. Códigos de status são usados da forma que a especificação HTTP pretende. Nenhum desses são bugs isoladamente; juntos eles são a diferença entre uma API que parece projetada e uma que parece montada.

Estilo da casa. Suas próprias convenções. Talvez cada endpoint deva ser marcado. Talvez DELETE deva retornar 204. Talvez campos internos devam ser prefixados. Estas são as regras que ninguém mais tem, e a capacidade de escrevê-las é o que separa um linter com o qual você pode conviver de um com o qual você briga.

Uma regra tem uma severidade: erro, aviso, informação ou dica. Erros falham a build; avisos aparecem, mas permitem que ela passe. Esse seletor de severidade é o que permite que você adote o linting em uma API existente sem se afogar em 4.000 violações no primeiro dia. Comece tudo como aviso, corrija o pior e, em seguida, promova as regras para erro à medida que avança. Para o lado conceitual de por que essas regras importam e como as equipes as aplicam em escala, o contexto mais aprofundado está em como as principais empresas garantem a consistência do design de API.

As principais opções de linter OpenAPI

Aqui estão as ferramentas que vale a pena conhecer, com uma análise honesta de onde cada uma se encaixa.

Spectral

Spectral, da Stoplight, é o padrão de fato. É uma CLI e biblioteca de código aberto que faz lint em OpenAPI 2.0 e 3.x (e AsyncAPI, e qualquer JSON ou YAML via JSONPath). Ele vem com um conjunto de regras spectral:oas integrado que cobre as regras de bom senso, e sua verdadeira força são as regras personalizadas: você descreve o que verificar usando seletores given no estilo JSONPath mais uma função then, tudo em um arquivo YAML. Há um grande catálogo de funções integradas (truthy, pattern, casing, length, enumeration) e você pode usar JavaScript quando precisar de lógica que o formato declarativo não consegue expressar.

Pontos fortes: está em todo lugar, possui o maior ecossistema de regras, extensões de editor existem para VS Code e outros, e funciona em qualquer lugar onde o Node possa ser executado. Se você quer uma ferramenta que toda a indústria reconheça, esta é ela. A desvantagem é que escrever regras não triviais significa aprender JSONPath e, eventualmente, a API de funções do Spectral. Temos um guia completo sobre isso em construindo regras personalizadas do Spectral com TypeScript se você quiser se aprofundar na autoria.

Um .spectral.yaml mínimo:

extends: ["spectral:oas"]
rules:
  operation-operationId: error
  operation-description: warn
  property-casing:
    description: Properties must be camelCase
    given: $.components.schemas..properties[*]~
    severity: error
    then:
      function: casing
      functionOptions:
        type: camel

Para executar:

npx @stoplight/spectral-cli lint openapi.yaml

Redocly CLI

O CLI da Redocly agrupa linting com empacotamento e visualização de docs. Seu linter lê uma configuração redocly.yaml, vem com um conjunto de regras embutidas e suporta conjuntos de regras configuráveis, além de plugins personalizados escritos em JavaScript. Equipes que já usam Redocly para documentação obtêm linting na mesma cadeia de ferramentas sem adicionar uma dependência, e as regras embutidas tendem a focar no que faz os docs renderizarem bem.

Pontos fortes: integração estreita com um fluxo de trabalho de documentação e empacotamento, padrões decentes e um formato de configuração que parece familiar se você vive no ecossistema Redocly. Se você ainda não está lá, a biblioteca de regras é menor que a do Spectral e a história das regras personalizadas é menos amplamente documentada.

npx @redocly/cli lint openapi.yaml

Vacuum

Vacuum é um linter mais recente escrito em Go, construído para velocidade. Ele é compatível com conjuntos de regras do Spectral, então você pode apontá-lo para um .spectral.yaml existente e obter as mesmas verificações rodando muito mais rápido em grandes especificações. Para um monorepo com dezenas de grandes documentos de API, a diferença de tempo de execução é real.

Pontos fortes: rápido, compatível com conjuntos de regras do Spectral, binário único sem tempo de execução Node. Se sua especificação é pequena, o ganho de velocidade é invisível, e o ecossistema e as ferramentas do editor são mais jovens que os do Spectral, então é mais atraente como um acelerador de CI do que uma escolha do zero.

Swagger e openapi-spec-validator

Vale a pena nomeá-los para que você não os confunda com linters. O Swagger Editor e o swagger-cli/openapi-spec-validator verificam se um documento é um OpenAPI válido. Isso é apenas validade, não consistência ou estilo da casa. Eles passarão alegremente uma especificação onde cada propriedade é nomeada de forma diferente, porque nada na especificação OpenAPI proíbe isso. A validação é necessária, mas é o piso, não o teto. Se você está escolhendo entre ferramentas da família Swagger e uma plataforma de design completa, as compensações são apresentadas em alternativas ao Swagger que também testam sua API.

Verificações em tempo de design no Apidog

As ferramentas acima são executadas depois que você tem um arquivo. O outro lugar para detectar inconsistências é antes do arquivo existir, enquanto você está projetando o endpoint. Apidog é uma plataforma "design-first": você constrói endpoints e esquemas de dados em um editor visual, e ele mantém seu projeto internamente consistente à medida que você avança. Esquemas de dados reutilizáveis significam que o mesmo modelo é referenciado em todos os lugares, em vez de ser redefinido por endpoint, o que elimina toda uma classe de desvio de nomenclatura na origem. Componentes de resposta compartilhados fazem o mesmo para os formatos de erro.

Apidog não é um substituto direto para um conjunto de regras do Spectral; se você tem regras .spectral.yaml já commitadas, continue executando-as. O que o Apidog muda é o quanto o seu linter encontra em primeiro lugar. Quando a superfície de design impõe a reutilização, o linter passa de uma parede de violações para uma detecção ocasional. E como o Apidog importa e exporta OpenAPI 3.x padrão, o arquivo que você entrega ao Spectral ou Vacuum na CI é o mesmo artefato, então as duas camadas se complementam em vez de competir.

Uma configuração de linter que você pode executar hoje

Uma boa configuração executa a verificação em três lugares, cada um com uma função diferente. O editor oferece feedback instantâneo. O hook de pré-commit impede erros óbvios localmente. A CI é a barreira que ninguém pode pular. Aqui está cada camada.

Camada 1: o editor

Instale a extensão Spectral para VS Code e adicione um arquivo .spectral.yaml à raiz do seu repositório. A extensão o detecta automaticamente e sublinha as violações enquanto você edita a especificação, da mesma forma que um erro de digitação recebe um rabisco vermelho. Este é o ciclo de feedback mais barato possível, porque o desenvolvedor corrige o problema antes que ele se torne um commit. Nada mais para configurar; o arquivo no repositório é a única fonte de verdade para as regras.

Camada 2: pré-commit

Adicione um hook para que uma especificação quebrada nunca chegue ao repositório remoto. Usar um script package.json mais um hook Git é suficiente:

{
  "scripts": {
    "lint:api": "spectral lint openapi.yaml --fail-severity=error"
  }
}
# .git/hooks/pre-commit  (ou via husky)
#!/bin/sh
npm run lint:api || {
  echo "O lint OpenAPI falhou. Corrija a especificação antes de commitar."
  exit 1
}

A flag --fail-severity=error é a parte importante. Ela instrui o linter a sair com código diferente de zero apenas em caso de erros, então os avisos ainda são impressos sem bloquear o commit. Isso mantém o hook utilizável enquanto você ainda está promovendo regras.

Camada 3: CI

Esta é a barreira que importa, porque é a única que um colega de equipe não pode ignorar com --no-verify. Um passo do GitHub Actions:

name: API lint
on: [pull_request]
jobs:
  spectral:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npx @stoplight/spectral-cli lint openapi.yaml --fail-severity=error

A tarefa falha quando a especificação quebra uma regra de nível de erro, o pull request mostra uma marca vermelha e a fusão é bloqueada até que alguém a corrija. Esse é todo o mecanismo de aplicação. Sem dashboards, sem reclamações; a regra é verde ou não é.

Camada 4: testar a API que a especificação descreve

Um linter prova que a especificação está bem formada e consistente. Ele não diz nada sobre se a API em execução corresponde à especificação. Essa lacuna é onde o desvio de contrato se esconde: um documento lindamente lintado descrevendo um comportamento que o servidor parou de honrar há três lançamentos. Para fechá-la, você executa testes contra a API ativa no mesmo pipeline.

É aqui que o Apidog CLI se encaixa ao lado do seu linter. Ele é um pacote npm, apidog-cli, e executa seus cenários de teste Apidog pela linha de comando para que se encaixem na CI logo após a etapa de lint:

npm install -g apidog-cli
apidog run --access-token $APIDOG_ACCESS_TOKEN -t 605067 -e 1629989 -r cli,junit

O comando apidog run sai com código diferente de zero quando um teste falha, o mesmo contrato em que cada etapa da CI confia, então um teste falho bloqueia a fusão exatamente da mesma forma que um lint falho. O reporter -r junit emite XML que seu dashboard de CI analisa em uma árvore de aprovação/reprovação, e -e aponta os mesmos cenários para staging ou produção sem duplicá-los. O CLI também pode importar um documento OpenAPI 3.x, então o arquivo que seu linter verifica é o mesmo arquivo que o Apidog testa. Para o padrão de pipeline completo, incluindo reporters e tratamento de códigos de saída, consulte o guia sobre como executar o Apidog CLI em seu pipeline CI/CD. Se você estiver especificamente no GitHub, o Apidog CLI no GitHub Actions tem um fluxo de trabalho de copiar e colar.

Lintar primeiro, testar depois. A etapa de lint é rápida e detecta problemas de design; a etapa de teste é mais lenta e detecta problemas de comportamento. Execute-os como duas etapas e um pull request terá que passar por ambas.

Escolhendo e adotando um conjunto de regras sem dor de cabeça

Escolher a ferramenta é a parte fácil. Adotá-la em uma API que já existe é onde as equipes emperram, porque a primeira execução em uma especificação madura retorna centenas de violações e a reação óbvia é desligar tudo.

Não comece com zero regras e não comece com todas as regras no nível de erro. Comece com o conjunto de regras integrado (spectral:oas) com tudo o que você adicionar definido como warn (aviso). Execute-o, leia a contagem e corrija os erros de validade primeiro, pois são bugs reais. Em seguida, escolha as duas ou três regras de consistência que mais importam para seus clientes (geralmente o padrão de maiúsculas/minúsculas das propriedades e um único formato de erro) e promova apenas essas para error (erro). Todo o resto permanece como aviso. A cada sprint, promova mais um ou dois avisos para erros à medida que a base de código se atualiza. Dentro de um trimestre, todo o conjunto de regras será aplicado e ninguém precisou parar de entregar para chegar lá.

Escreva regras de estilo da casa com moderação. Cada regra personalizada é um código que alguém terá que manter e explicar para o próximo contratado. Uma regra ganha seu lugar apenas quando uma violação realmente o prejudicou, não porque ela poderia. Para as regras que você escreve, apoie-se na camada de design para torná-las raras: se seus schemas forem reutilizados de uma definição central, uma regra de padrão de maiúsculas/minúsculas das propriedades quase nunca é acionada porque há um único local onde o nome é definido. A estrutura conceitual de quais regras vale a pena aplicar, versus quais são discussões triviais, é abordada em melhores práticas de design de API.

Se você projeta em uma linguagem diferente do YAML puro, o linter ainda se aplica. O TypeSpec compila para OpenAPI, e você faz o lint do documento emitido da mesma forma; o linter não se importa como o arquivo foi criado, apenas com o que ele diz.

Onde o linter se encaixa no ciclo de design maior

Um linter é um controle em um fluxo de trabalho "design-first", não a coisa toda. O ciclo completo é: projetar o contrato, fazer o lint, simular para que os clientes possam construir sobre ele, testar a implementação contra ele e publicar a documentação a partir dele. Pule qualquer etapa e as outras perdem valor. Uma especificação lintada que ninguém simula ainda bloqueia o trabalho de frontend. Uma especificação simulada que ninguém testa ainda se desvia da realidade.

A razão para colocar o design em primeiro lugar nesse ciclo é a mesma razão pela qual o linting funciona: detectar problemas onde eles são mais baratos de corrigir. Mudar o nome de uma propriedade na ferramenta de design é uma edição. Mudar depois que três equipes já lançaram com o nome antigo é uma migração. O linter impõe a consistência no arquivo; um processo "design-first" impõe isso na decisão antes que o arquivo exista. Se você quiser o argumento mais amplo para a sequência, API-first vs API design-first vs code-first apresenta as compensações, e ferramentas de design de API contract-first cobrem as ferramentas que o suportam.

botão

Apidog cobre todo esse ciclo em um só lugar: projete com esquemas reutilizáveis, simule instantaneamente, teste com o CLI na CI e exporte um OpenAPI limpo para qualquer linter que você padronizar. O linter ainda tem um trabalho; há apenas menos para ele detectar.

botão

Pratique o design de API no Apidog

Descubra uma forma mais fácil de construir e usar APIs