Input (.proto-skjema)

Output (JSON Schema)

Hva dette verktøyet gjør

Du har et Protocol Buffers-skjema og en tjeneste som tar imot JSON — kanskje en webhook-handler, kanskje en HTTP-transcoded gRPC-gateway, kanskje en API-gateway som validerer forespørselen før den når koden din. Du vil ha et JSON Schema-dokument som speiler proto'en, slik at du kan validere innkommende payloads, generere OpenAPI-fragmenter eller mate det inn i structured-output prompts. Denne konvertereren gjør det i nettleseren din — lim inn .proto'en, kopier JSON Schema, slipp det inn i validator-konfigurasjonen din.

Outputtet er JSON Schema draft 2020-12 — det nåværende draftet, støttet av enhver moderne validator, inkludert Ajv. Hver message blir en oppføring under $defs med type: "object" og en properties-map. Hver enum blir en $defs-oppføring med type: "string" og verdinavnene listet under enum — på linje med hvordan proto3 serialiserer enums etter navn i JSON. Field-referanser løser via $ref: "#/$defs/MessageName" med leaf-navnet, så nestede typer forblir lesbare.

Type-mappingen følger spesifikasjonen for proto3-JSON-mapping. string/bool mapper direkte. 32-bits ints får type: "integer" med format: "int32"; unsigned 32-bit legger på minimum: 0. 64-bits ints blir type: "string" med format: "int64" og et numerisk pattern, fordi JSON Numbers mister presisjon over 2^53, og proto3 koder 64-bits heltall som quoted strings på wiren. bytes blir en string med contentEncoding: "base64". Well-known-typer som google.protobuf.Timestamp mapper til format: "date-time" ifølge RFC 3339. Konverteringen kjører helt i nettleseren din — skjemaet ditt forlater ikke siden.

Slik bruker du det

Tre steg. Outputtet er ett enkelt JSON Schema-dokument du kan gi rett til en validator.

1

Lim inn .proto-skjemaet ditt

Slipp skjemaet i editoren til venstre. syntax = "proto3"; i toppen er greit, men valgfritt. Parseren håndterer nestede message-blokker, enum-deklarasjoner, oneof, map<K, V> og field options. import-direktiver gjenkjennes, men hoppes over — lim inn importerte typer inline om du trenger dem.

Field-navn forblir i snake_case (på linje med hva proto3-JSON-encoderen sender ut som standard — ingen transformasjon). Hvis klienten din setter preserve_proto_field_names = false, bytt property-nøklene til camelCase for hånd.

2

Les skjemaet

Til høyre: et JSON Schema 2020-12-dokument med $id, title, en top-level $ref som peker på din sist deklarerte rot-message, og en $defs-blokk som holder hver message og enum fra filen. Hver message blir et objekt-skjema med en properties-map; hver enum blir et string-skjema med verdinavnene. Les guiden Understanding JSON Schema hvis du trenger en oppfriskning på $ref- eller $defs-semantikken.

3

Heng det på en validator

Lagre outputtet som schema.json, last det inn i Ajv (Node) eller jsonschema (Python) eller den validatoren stacken din bruker, og kjør det så mot JSON-en din gRPC-gateway eller webhook tar imot. Avvik kommer ut som lesbare feilstier av typen /items/0/sku must be string. Det samme skjemaet kan også mate komponentdefinisjoner i OpenAPI 3.1 eller structured-output prompts til en LLM.

Når det faktisk sparer tid

Validere webhooks definert i proto

Teamet ditt bruker Protobuf som sannhetskilde for en OrderShipped-hendelse, men den faktiske webhook-mottakeren får JSON — det er ingen proto-runtime på mottakersiden. Lim inn .proto'en, slipp JSON Schema inn i Ajv, og avvis misformede payloads ved kanten før de når forretningslogikken. En SKU-101 med manglende quantity når aldri databasen.

Bygge OpenAPI 3.1 fra gRPC-skjemaer

Du skriver OpenAPI 3.1-specs for en gRPC-gateway. OpenAPI 3.1 er JSON Schema 2020-12-kompatibel, så $defs-blokken her detter rett under components.schemas etter en liten gjendøping. Ingen protoc-gen-openapi-plugin å installere, ingen Buf CLI å sette opp — bare lim inn, rediger, commit.

LLM structured outputs fra et proto

Du vil at OpenAI eller Anthropic skal returnere et typet Order-objekt som matcher det eksisterende .proto'et ditt. Lim inn skjemaet, ta $defs/Order-oppføringen og send den som JSON Schema i response_format. Modellen produserer nå output som gjør round-trip gjennom gRPC-tjenesten din uten manuell coercion.

Reviewe en Protobuf-API-endring

En backend-kollega la til to fields i Address og ga et enum-verdi nytt navn. Du vil se hvordan det påvirker JSON Schema-en din gateway bruker uten å kjøre hele codegen-pipelinen. Lim inn det nye .proto'et, diff skjemaet mot din committede kopi, legg igjen en fokusert review-kommentar på PR-en.

Vanlige spørsmål

Sendes skjemaet mitt noe sted?

Nei. Parseren og JSON Schema-emitteren kjører helt i nettleseren din som JavaScript. Åpne DevTools og se på Network-fanen mens du limer inn — null requests. Nyttig når skjemaet inneholder interne package-paths, typenavn eller noe du ikke vil overlate til en tredjepartstjeneste.

Hvilket JSON Schema-draft sikter outputtet på?

Draft 2020-12, det nåværende publiserte draftet. $schema-URI-en på hvert output-dokument er https://json-schema.org/draft/2020-12/schema. Se 2020-12 release notes for hva som er endret siden 2019-09. Enhver aktivt vedlikeholdt validator (Ajv 8+, jsonschema 4+ for Python, NJsonSchema, Justify for Java) støtter 2020-12 som standard.

Hvorfor er int64-fields strings, ikke integers?

Fordi det er det spesifikasjonen for proto3-JSON-mapping sier, og den har rett. JSON Numbers er IEEE-754-doubles, som mister presisjon over 2^53. En ekte int64 kan bære verdier langt over det taket — ordre-ID-er, timestamps i nanos, ledger-saldoer — så proto3 koder 64-bits heltall som quoted JSON-strings. Skjemaet speiler det med type: "string", format: "int64" og et numerisk pattern, slik at en validator fortsatt avviser "abc". Hvis serveren din leverer ut 64-bits ints som rå JSON Numbers (noen legacy-gateways gjør det), gjør de oppføringene om til { "type": "integer" } for hånd.

Hvorfor er enums strings, ikke integers?

Samme grunn — det er proto3's standard JSON-encoding. Enums serialiseres som verdinavnet ("ORDER_STATUS_PAID") heller enn det heltallige wire-nummeret (2). Det gjør JSON-payloads lesbare og skjemaet enklere. Heltallsnumrene er ikke i JSON Schema fordi de er en wire-format-sak, ikke en valideringssak. Har du en non-default encoder konfigurert til å sende ints, bytt type: "string" mot type: "integer" på enum-oppføringen.

Hvordan håndterer den map<K, V>?

Rendres som { "type": "object", "additionalProperties": <V-schema> }. JSON-objektnøkler er alltid strings, så en proto-map med en ikke-string-nøkkel (f.eks. map<int32, string>) får en description-note som forklarer at runtime-nøklene blir string-coercet. Verdiskjemaet følger de samme type-mapping-reglene som et vanlig field.

Markeres fields som required?

Nei — proto3-fields har alltid en default i wire-formatet og er alltid til stede i JSON-outputtet (med tomme defaults som "", 0, false, [], {}), så skjemaet lister ikke noe under required. Vil du virkelig at et field skal være required ved validering, legg det til i en required-array på parent-messaget for hånd. proto3 optional-fields og oneof tvinges heller ikke som oneOf i outputtet — det er runtime-semantikk som JSON Schema ikke kan uttrykke fullt ut uten ekstra annotasjoner.

Hvordan refereres nestede messages?

Hver message og enum heises opp til en flat $defs-blokk nøklet etter sitt leaf-navn. Field-referanser går via $ref: "#/$defs/MessageName". Flatleggingen holder dokumentet kompakt og betyr at dobbeltnestede typer ikke dupliseres. Hvis to messages i ulike packages deler et leaf-navn, beholder konvertereren den første definisjonen — del kolliderende navn opp før du limer inn om det betyr noe.

Kan jeg stikke det rett inn i Ajv?

Ja. ajv.compile(schema) på outputtet fungerer rett ut av esken så snart Ajv er konfigurert for draft 2020-12 (new Ajv2020() fra ajv/dist/2020). $ref-oppføringene løses internt fordi alt ligger i samme dokument. Vil du ha format-validering (date-time, duration), legg til ajv-formats ved siden av.

Relaterte verktøy

Hvis du roter med Protobuf, JSON Schema og validering, passer disse godt sammen: