Entrada (esquema .proto)

Saída (OpenAPI YAML)

O que esta ferramenta faz

Você tem um esquema Protocol Buffers e um time de frontend, parceiro ou QA que quer um documento OpenAPI com as mesmas formas — geralmente porque o serviço gRPC também está exposto via HTTP por algo como o grpc-gateway. Configurar protoc-gen-openapiv2 no seu build é a resposta certa para produção, mas é exagero quando você só precisa de um spec rápido para compartilhar ou jogar num Swagger UI. Este conversor faz a metade de esquema do trabalho dentro do navegador — cole o .proto, copie o YAML, você tem components OpenAPI válidos.

A saída é um documento OpenAPI 3.1.0 mínimo mas válido, com um paths: {} vazio e uma entrada por message ou enum do Protobuf em components.schemas. Escolhemos OpenAPI 3.1 especificamente porque o modelo de dados se alinha com o JSON Schema 2020-12 — é a versão em que formatos como int64, date-time e duration são cidadãos de primeira classe e em que $ref pode conviver com outras keywords sem os truques de reescrita do velho 3.0.

O mapeamento de tipos segue o mapeamento JSON do proto3: inteiros de 32 bits viram type: integer, format: int32, inteiros de 64 bits viram type: string, format: int64 com um pattern numérico (porque números JSON acima de 2^53 perdem precisão), repeated T vira um array, map<K, V> vira um objeto com additionalProperties e os nomes de campo permanecem em snake_case para que o esquema combine com o que seu servidor de fato serializa. Enums saem como type: string com uma lista enum de nomes de valores — igual ao JSON do proto3. O conversor roda inteirinho no seu navegador; nada do seu esquema sai da página.

Como usar

Três passos. A saída é um documento YAML que você pode jogar num Swagger UI ou mesclar num spec existente.

1

Cole seu esquema .proto

Solte o esquema no editor da esquerda. syntax = "proto3"; no topo é tranquilo, mas é opcional. O parser lida com blocos message aninhados, declarações enum, oneof, map<K, V> e options de campos. Statements import entre arquivos são reconhecidos mas ignorados — cole os tipos importados inline se seus esquemas se referenciam.

Os nomes de campo permanecem em snake_case na saída, casando com o comportamento padrão do encoder JSON do proto3. Se seu gateway está configurado para nomes JSON em camelCase, faça localizar-substituir na saída ou troque a configuração do gateway.

2

Leia a saída OpenAPI

À direita: um documento YAML com openapi: 3.1.0, um bloco info, um paths: {} vazio e seus messages e enums sob components.schemas. Referências a messages aninhados usam $ref: '#/components/schemas/MessageName' contra o nome folha, então referências planas funcionam mesmo quando seu .proto declara tipos aninhados.

3

Conecte tudo

Solte o arquivo numa instância do Swagger UI ou do Redoc para ver como os esquemas renderizam. Para virar um spec completo, adicione entradas reais de paths apontando para suas rotas do grpc-gateway (ou escreva à mão) — referencie com $ref em #/components/schemas/Order e está pronto.

Quando isso realmente economiza tempo

Compartilhar um esquema com um time de frontend ou parceiro

Um time de frontend está consumindo seu serviço transcodificado de gRPC. Eles pediram um doc OpenAPI para encaixar no gerador de tipos ou no API explorer deles. Cole o .proto, copie o YAML, mande. Eles recebem o esquema num formato que o tooling deles já entende.

Bootstrappar o spec de uma nova API HTTP transcodificada

Você está subindo um serviço novo que vai rodar tanto como gRPC quanto HTTP via grpc-gateway com buf. A seção components/schemas é mecânica — gere com esta ferramenta e depois escreva à mão os paths com os templates de rota corretos. Mais rápido do que montar tudo na mão.

Manter um Swagger UI sincronizado com mudanças no .proto

Seu time usa Swagger UI para o doc legível da API, mas a fonte da verdade vive em arquivos .proto. Um colega de backend adiciona shipping_address em Order; você regenera a seção de schemas aqui, cola de volta no spec e publica a atualização do doc.

Sanity-check da saída do codegen

Você rodou protoc-gen-openapiv2 como parte do build e veio um YAML de 4000 linhas. Para verificar se um message específico está com a forma certa, cole só aquele .proto aqui e compare. Referência rápida de como deve ser um mapeamento OpenAPI 3.1 limpinho.

Perguntas comuns

Por que OpenAPI 3.1 e não 3.0?

OpenAPI 3.1 alinha o modelo de dados com o JSON Schema 2020-12, ou seja, formatos como int64, date-time e duration estão bem definidos e dá para colocar $ref ao lado de outras keywords sem as gambiarras esquisitas que o 3.0 exigia. A maioria das ferramentas modernas (Redoc, Swagger UI 5, Stoplight, Spectral) fala 3.1 numa boa. Se você realmente precisa de saída 3.0 para tooling legado, troque openapi: 3.1.0 no topo do documento — o resto é compatível o suficiente para ainda validar na maior parte dos casos.

Por que int64 sai como string e não como número?

Números JSON são doubles IEEE-754 na prática — perdem precisão acima de 2^53. O mapeamento JSON oficial do proto3 diz que int64, uint64, fixed64, sfixed64 e sint64 precisam ser codificados como strings JSON. Por isso o esquema OpenAPI usa type: string, format: int64, pattern: "^-?[0-9]+$" para casar com o que o servidor realmente manda. Se você quiser assumir valores pequenos e usar type: integer, faça localizar-substituir na saída.

Por que paths está vazio?

Arquivos .proto descrevem messages e serviços, não rotas HTTP. A transcodificação HTTP (path, method, query, body) é configurada em separado — geralmente via anotações google.api.http ou opções do grpc-gateway. Não fazemos parsing disso, então deixamos paths: {} para você preencher. A parte components/schemas é a metade reusável e mecânica — é isso que esta ferramenta entrega.

Por que os nomes de campo estão em snake_case?

Porque é o que o JSON do proto3 codifica por padrão. order_id no .proto serializa como "order_id" no formato JSON, a não ser que você ative a opção camelCase (preserve_proto_field_names em alguns encoders, ou a flag do lado do gateway). Manter o esquema OpenAPI em snake_case significa que ele bate com o JSON que seu servidor de fato manda. Se sua stack usa camelCase, passe a saída por um localizar-substituir.

Como messages aninhados são tratados?

Cada message Protobuf vira uma entrada de topo em components.schemas indexada pelo nome folha (Address, não commerce.v1.Address). As referências usam $ref: '#/components/schemas/Address'. Se dois messages têm o mesmo nome folha em packages diferentes, o segundo sobrescreve o primeiro — separe em documentos distintos ou renomeie no .proto.

A ferramenta entende bem os well-known types do google.protobuf?

Alguns. google.protobuf.Timestamp renderiza como type: string, format: date-time; Duration como type: string, format: duration; Empty como objeto vazio; Any como objeto genérico; Value como {} (qualquer valor JSON). Para outros well-known types do Google, o conversor hoje emite um $ref para o nome folha — você pode definir esses esquemas você mesmo ou trocar as referências pelo tipo primitivo correto.

Ferramentas relacionadas

Se você está mexendo com Protobuf e OpenAPI/JSON Schema, estas combinam bem: