Input (schema .proto)

Output (OpenAPI YAML)

Cosa fa questo strumento

Hai uno schema Protocol Buffers e un team frontend, partner o QA che vuole un documento OpenAPI per le stesse forme — di solito perché il servizio gRPC è esposto anche su HTTP tramite qualcosa come grpc-gateway. Inserire protoc-gen-openapiv2 nella build è la risposta giusta in produzione, ma è esagerato quando ti serve solo uno spec rapido da condividere o da buttare in una Swagger UI. Questo convertitore fa la metà di schema del lavoro nel tuo browser — incolli il .proto, copi lo YAML, hai dei components OpenAPI validi.

L'output è un documento OpenAPI 3.1.0 minimo ma valido, con un paths: {} vuoto e un'entry per ogni message o enum Protobuf sotto components.schemas. Scegliamo OpenAPI 3.1 di proposito perché il suo modello dati si allinea con JSON Schema 2020-12 — è la versione in cui formati come int64, date-time e duration sono cittadini di prima classe e in cui $ref può convivere con altre keyword senza i vecchi hack di riscrittura della 3.0.

La mappatura dei tipi segue il mapping JSON di proto3: gli interi a 32 bit diventano type: integer, format: int32, quelli a 64 bit diventano type: string, format: int64 con un pattern numerico (perché i numeri JSON oltre 2^53 perdono precisione), repeated T diventa un array, map<K, V> diventa un oggetto con additionalProperties e i nomi dei campi rimangono in snake_case in modo che lo schema corrisponda a ciò che il tuo server effettivamente serializza. Gli enum vengono emessi come type: string con una lista enum di nomi di valori — come nel JSON di proto3. Il convertitore gira interamente nel tuo browser; nulla del tuo schema lascia la pagina.

Come si usa

Tre passaggi. L'output è un documento YAML che puoi buttare in una Swagger UI o fondere con uno spec esistente.

1

Incolla il tuo schema .proto

Lascia cadere lo schema nell'editor di sinistra. syntax = "proto3"; in cima va benissimo ma è opzionale. Il parser gestisce blocchi message annidati, dichiarazioni enum, oneof, map<K, V> e le option dei campi. Le import tra file vengono riconosciute ma saltate — incolla i tipi importati inline se i tuoi schemi si riferiscono l'uno all'altro.

I nomi dei campi rimangono in snake_case nell'output, in linea con il default dell'encoder JSON di proto3. Se il tuo gateway è configurato con nomi JSON in camelCase, fai un trova-sostituisci nell'output o cambia l'impostazione del gateway.

2

Leggi l'output OpenAPI

A destra: un documento YAML con openapi: 3.1.0, un blocco info, un paths: {} vuoto e i tuoi message ed enum sotto components.schemas. I riferimenti a message annidati usano $ref: '#/components/schemas/MessageName' sul nome foglia, quindi i riferimenti piatti funzionano anche quando il tuo .proto dichiara tipi annidati.

3

Collega il tutto

Lascia cadere il file in un'istanza di Swagger UI o di Redoc per vedere come vengono renderizzati gli schemi. Per trasformarlo in uno spec completo, aggiungi vere entry paths che puntano alle tue rotte grpc-gateway (o scrivile a mano) — referenziale con $ref a #/components/schemas/Order e sei a posto.

Quando ti fa davvero risparmiare tempo

Condividere uno schema con un team frontend o partner

Un team frontend sta consumando il tuo servizio gRPC transcodificato. Hanno chiesto un doc OpenAPI per agganciarlo al loro generatore di tipi o all'API explorer. Incolla il .proto, copia lo YAML, manda. Ricevono lo schema in un formato che la loro toolchain capisce già.

Fare il bootstrap dello spec di una nuova API HTTP transcodificata

Stai mettendo su un nuovo servizio che girerà sia come gRPC sia come HTTP via grpc-gateway con buf. La sezione components/schemas è meccanica — generala con questo strumento, poi scrivi a mano i paths con i template di rotta giusti. Più veloce che impostare tutto da zero a mano.

Tenere una Swagger UI in pari con i cambiamenti del .proto

Il tuo team usa Swagger UI per il doc API leggibile dagli umani, ma la fonte di verità vive nei file .proto. Un collega backend aggiunge shipping_address a Order; tu rigeneri qui la sezione schemas, la incolli di nuovo nello spec, spedisci l'aggiornamento del doc.

Sanity check sull'output del codegen

Hai eseguito protoc-gen-openapiv2 come parte della build e ti sei ritrovato con un YAML da 4000 righe. Per verificare che un message specifico abbia la forma giusta, incolla qui solo quel .proto e confronta. Riferimento veloce per come dovrebbe apparire una mappatura OpenAPI 3.1 pulita.

Domande frequenti

Perché OpenAPI 3.1 e non 3.0?

OpenAPI 3.1 allinea il proprio modello dati con JSON Schema 2020-12, il che significa che formati come int64, date-time e duration sono ben definiti e puoi mettere $ref accanto ad altre keyword senza gli scomodi workaround che servivano in 3.0. La maggior parte degli strumenti moderni (Redoc, Swagger UI 5, Stoplight, Spectral) gestisce 3.1 senza problemi. Se hai davvero bisogno dell'output 3.0 per tooling legacy, cambia openapi: 3.1.0 in cima al documento — il resto è abbastanza compatibile da continuare a validare nella maggior parte dei casi.

Perché int64 viene emesso come stringa e non come numero?

I numeri JSON sono in pratica double IEEE-754 — perdono precisione sopra 2^53. Il mapping JSON ufficiale di proto3 dice che int64, uint64, fixed64, sfixed64 e sint64 devono essere codificati come stringhe JSON. Quindi lo schema OpenAPI usa type: string, format: int64, pattern: "^-?[0-9]+$" per coincidere con quello che il server effettivamente invia. Se vuoi assumere valori piccoli e usare type: integer, fai un trova-sostituisci nell'output.

Perché paths è vuoto?

I file .proto descrivono message e servizi, non rotte HTTP. La transcodifica HTTP (path, method, query, body) si configura a parte — di solito tramite annotazioni google.api.http oppure opzioni di grpc-gateway. Non le parsiamo, quindi lasciamo paths: {} da riempire a te. La parte components/schemas è la metà riusabile e meccanica — è quello che ti dà questo strumento.

Perché i nomi dei campi sono in snake_case?

Perché è ciò che il JSON di proto3 codifica per default. order_id nel .proto si serializza come "order_id" nel formato JSON a meno che tu non attivi l'opzione camelCase (preserve_proto_field_names in alcuni encoder, oppure il flag lato gateway). Tenere lo schema OpenAPI in snake_case significa che combacia con il JSON che il tuo server manda davvero. Se il tuo stack usa camelCase, passa l'output da un trova-sostituisci.

Come vengono gestiti i message annidati?

Ogni message Protobuf diventa un'entry top-level sotto components.schemas indicizzata sul nome foglia (Address, non commerce.v1.Address). I riferimenti usano $ref: '#/components/schemas/Address'. Se due message hanno lo stesso nome foglia in package diversi, il secondo sovrascrive il primo — separali in documenti distinti oppure rinominali nel .proto.

Capisce bene i well-known type di google.protobuf?

Alcuni sì. google.protobuf.Timestamp diventa type: string, format: date-time; Duration diventa type: string, format: duration; Empty un oggetto vuoto; Any un oggetto generico; Value diventa {} (qualunque valore JSON). Per gli altri well-known type di Google il convertitore al momento emette un $ref al nome foglia — puoi definire tu quegli schemi oppure sostituire i riferimenti con il tipo primitivo corretto.

Strumenti correlati

Se stai lavorando con Protobuf e OpenAPI/JSON Schema, questi si abbinano bene: