Inndata (.proto-skjema)

Utdata (OpenAPI YAML)

Hva verktøyet gjør

Du har et Protocol Buffers-skjema og et frontend-, partner- eller QA-team som vil ha et OpenAPI-dokument for de samme formene — som regel fordi gRPC-tjenesten også er eksponert over HTTP via noe slikt som grpc-gateway. Å sette opp protoc-gen-openapiv2 i bygget er det riktige svaret i produksjon, men det er overkill når du bare trenger et raskt spec å dele eller dra inn i en Swagger UI. Denne konverteren tar skjema-halvparten av jobben i nettleseren — lim inn .proto-en, kopier YAML-en, og du har gyldige OpenAPI-components.

Utdataen er et minimalt, men gyldig OpenAPI 3.1.0-dokument med en tom paths: {} og én oppføring per Protobuf-melding eller -enum under components.schemas. Vi velger spesifikt OpenAPI 3.1 fordi datamodellen flukter med JSON Schema 2020-12 — det er versjonen der formater som int64, date-time og duration er førsteklasses, og der $ref kan stå ved siden av andre nøkkelord uten de gamle 3.0-omskrivingstriksene.

Typemappingen følger proto3-JSON-mappingen: 32-bits heltall blir type: integer, format: int32, 64-bits heltall blir type: string, format: int64 med et numerisk pattern (fordi JSON-tall over 2^53 mister presisjon), repeated T blir et array, map<K, V> blir et objekt med additionalProperties, og feltnavnene forblir i snake_case slik at skjemaet matcher det serveren faktisk serialiserer. Enums sendes ut som type: string med en enum-liste over verdienavn — som i proto3-JSON. Konverteren kjører i sin helhet i nettleseren; ingenting fra skjemaet ditt forlater siden.

Slik bruker du den

Tre trinn. Utdataen er et YAML-dokument du kan dra inn i en Swagger UI eller flette inn i et eksisterende spec.

1

Lim inn .proto-skjemaet ditt

Slipp skjemaet i editoren til venstre. syntax = "proto3"; øverst er greit, men valgfritt. Parseren håndterer nestede message-blokker, enum-deklarasjoner, oneof, map<K, V> og feltvalg. import-setninger på tvers av filer blir gjenkjent, men hoppet over — lim inn importerte typer inline hvis skjemaene refererer hverandre.

Feltnavnene forblir snake_case i utdataen, i tråd med standardoppførselen til proto3-JSON-encoderen. Hvis gatewayen din er konfigurert til camelCase JSON-navn, kjør et søk-og-erstatt i utdataen, eller endre gateway-innstillingen.

2

Les OpenAPI-utdataen

Til høyre: et YAML-dokument med openapi: 3.1.0, en info-blokk, en tom paths: {} og meldingene og enumene dine under components.schemas. Referanser til nestede meldinger bruker $ref: '#/components/schemas/MessageName' mot bladnavnet, så flate referanser virker selv når .proto-en din erklærer nestede typer.

3

Kobl det sammen

Slipp filen inn i en Swagger UI- eller Redoc-instans for å se hvordan skjemaene rendres. For å gjøre det om til et fullstendig spec legger du til ekte paths-oppføringer som peker på grpc-gateway-rutene dine (eller skriver dem for hånd) — referer dem med $ref mot #/components/schemas/Order, så er du i mål.

Når det faktisk sparer tid

Dele et skjema med et frontend- eller partnerteam

Et frontendteam konsumerer den gRPC-transkodede tjenesten din. De har bedt om et OpenAPI-doc de kan dytte inn i typegeneratoren eller API-utforskeren sin. Lim inn .proto-en, kopier YAML-en, send avgårde. De får skjemaet i et format toolingen deres allerede forstår.

Bootstrappe specet for et nytt HTTP-transkodet API

Du setter opp en ny tjeneste som skal kjøre både som gRPC og HTTP via grpc-gateway med buf. components/schemas-seksjonen er mekanisk — generer den med dette verktøyet, og skriv så paths for hånd med riktige rutemaler. Raskere enn å meisle ut alt manuelt.

Holde en Swagger UI synkronisert med endringer i .proto

Teamet ditt bruker Swagger UI til den menneskelesbare API-doc-en, men sannheten bor i .proto-filer. En backend-kollega legger til shipping_address i Order; du regenererer schemas-seksjonen her, limer den tilbake i specet og sender ut doc-oppdateringen.

Sjekke codegen-utdata for fornuft

Du kjørte protoc-gen-openapiv2 som en del av bygget og fikk en YAML-fil på 4000 linjer. For å verifisere at en bestemt melding har riktig form, limer du bare inn den ene .proto-filen her og sammenligner. Rask referanse for hvordan en ren OpenAPI 3.1-mapping bør se ut.

Vanlige spørsmål

Hvorfor OpenAPI 3.1 og ikke 3.0?

OpenAPI 3.1 legger datamodellen sin på linje med JSON Schema 2020-12, noe som betyr at formater som int64, date-time og duration er godt definert, og at du kan ha $ref ved siden av andre nøkkelord uten de klønete løsningene 3.0 krevde. Det meste av moderne tooling (Redoc, Swagger UI 5, Stoplight, Spectral) snakker 3.1 helt fint. Hvis du virkelig trenger 3.0-utdata til legacy-tooling, så endre openapi: 3.1.0 øverst i dokumentet — resten er kompatibelt nok til at det som regel fortsatt validerer.

Hvorfor sendes int64 ut som streng og ikke tall?

JSON-tall er i praksis IEEE-754-doubles — de mister presisjon over 2^53. Den offisielle proto3-JSON-mappingen krever at int64, uint64, fixed64, sfixed64 og sint64 kodes som JSON-strenger. Derfor bruker OpenAPI-skjemaet type: string, format: int64, pattern: "^-?[0-9]+$" for å matche det serveren faktisk sender. Hvis du vil anta små verdier og bruke type: integer i stedet, kjør et søk-og-erstatt i utdataen.

Hvorfor er paths tom?

.proto-filer beskriver meldinger og tjenester, ikke HTTP-ruter. HTTP-transkodingen (path, method, query, body) konfigureres separat — vanligvis via google.api.http-annotasjoner eller grpc-gateway-valg. Dem parser vi ikke, så vi lar paths: {} ligge tom for at du skal fylle den ut. components/schemas-delen er den gjenbrukbare, mekaniske halvparten — og det er det dette verktøyet gir deg.

Hvorfor er feltnavnene i snake_case?

Fordi det er slik proto3-JSON koder dem som standard. order_id i .proto-en serialiseres til "order_id" i JSON-wireformatet, med mindre du skrur på camelCase-valget (preserve_proto_field_names i noen enkodere, eller flagget på gateway-siden). Å holde OpenAPI-skjemaet i snake_case betyr at det matcher JSON-en serveren faktisk sender. Hvis stacken din kjører camelCase, så send utdataen gjennom et søk-og-erstatt.

Hvordan håndteres nestede meldinger?

Hver Protobuf-melding blir en topp-nivå-oppføring under components.schemas indeksert på bladnavnet (Address, ikke commerce.v1.Address). Referanser bruker $ref: '#/components/schemas/Address'. Har to meldinger samme bladnavn i forskjellige pakker, vil den andre overskrive den første — del dem opp i separate dokumenter, eller døp dem om i .proto-en.

Forstår den google.protobuf well-known types ordentlig?

Noen av dem. google.protobuf.Timestamp rendres som type: string, format: date-time; Duration som type: string, format: duration; Empty som et tomt objekt; Any som et generisk objekt; Value som {} (hvilken som helst JSON-verdi). For andre Google well-known types sender konverteren foreløpig ut en $ref til bladnavnet — du kan enten definere de skjemaene selv eller bytte ut referansene med riktig primitiv type.

Relaterte verktøy

Hvis du jobber med Protobuf og OpenAPI/JSON Schema, så går disse godt sammen: