Input (.proto-skema)

Output (JSON Schema)

Hvad det her værktøj gør

Du har et Protocol Buffers-skema og en service, der modtager JSON — måske en webhook-handler, måske en HTTP-transcoded gRPC-gateway, måske en API-gateway, der validerer requesten før den rammer din kode. Du vil have et JSON Schema-dokument, der spejler proto'en, så du kan validere indkommende payloads, generere OpenAPI-fragmenter eller fodre det ind i structured-output prompts. Den her konverter klarer det i din browser — indsæt .proto'en, kopiér JSON Schema, smid det i din validator-config.

Outputtet er JSON Schema draft 2020-12 — det nuværende draft, understøttet af enhver moderne validator inklusive Ajv. Hver message bliver til en post under $defs med type: "object" og en properties-map. Hver enum bliver til en $defs-post med type: "string" og værdinavnene listet under enum — på linje med hvordan proto3 serialiserer enums efter navn i JSON. Field-referencer løses via $ref: "#/$defs/MessageName" med leaf-navnet, så nestede typer forbliver læsbare.

Type-mappingen følger specifikationen for proto3-JSON-mapping. string/bool mapper direkte. 32-bit ints får type: "integer" med format: "int32"; unsigned 32-bit lægger minimum: 0 oveni. 64-bit ints bliver til type: "string" med format: "int64" og et numerisk pattern, fordi JSON Numbers mister præcision over 2^53 og proto3 koder 64-bit heltal som quoterede strings på wiren. bytes bliver en string med contentEncoding: "base64". Well-known-typer som google.protobuf.Timestamp mapper til format: "date-time" ifølge RFC 3339. Konverteringen kører helt i din browser — dit skema forlader ikke siden.

Sådan bruger du det

Tre trin. Outputtet er ét enkelt JSON Schema-dokument, som du kan give direkte til en validator.

1

Indsæt dit .proto-skema

Smid skemaet i editoren til venstre. syntax = "proto3"; i toppen er fint, men valgfrit. Parseren håndterer nestede message-blokke, enum-deklarationer, oneof, map<K, V> og field options. import-direktiver bliver genkendt, men sprunget over — indsæt importerede typer inline, hvis du har brug for dem.

Field-navne forbliver i snake_case (på linje med hvad proto3-JSON-encoderen sender ud som standard — ingen transformation). Hvis din klient sætter preserve_proto_field_names = false, så skift property-nøglerne til camelCase i hånden.

2

Læs skemaet

Til højre: et JSON Schema 2020-12-dokument med $id, title, en top-level $ref, der peger på din senest deklarerede rod-message, og en $defs-blok, der holder hver message og enum fra filen. Hver message bliver et objekt-skema med en properties-map; hver enum bliver et string-skema med værdinavnene. Læs guiden Understanding JSON Schema, hvis du har brug for en opfriskning af $ref- eller $defs-semantikken.

3

Hægt det på en validator

Gem outputtet som schema.json, indlæs det i Ajv (Node) eller jsonschema (Python) eller den validator din stack bruger, og kør det så mod den JSON, din gRPC-gateway eller webhook modtager. Misforhold kommer ud som læsbare fejlstier som /items/0/sku must be string. Det samme skema kan også fodre OpenAPI 3.1-komponentdefinitioner eller structured-output prompts til en LLM.

Hvornår det rent faktisk sparer tid

Validér webhooks defineret i proto

Dit team bruger Protobuf som sandhedskilde for en OrderShipped-event, men den faktiske webhook-modtager får JSON — der er ingen proto-runtime på modtagersiden. Indsæt .proto'en, smid JSON Schema i Ajv og afvis misformede payloads ved kanten, før de rammer forretningslogikken. En SKU-101 med manglende quantity når aldrig databasen.

Bygge OpenAPI 3.1 fra gRPC-skemaer

Du skriver OpenAPI 3.1-specs til en gRPC-gateway. OpenAPI 3.1 er JSON Schema 2020-12-kompatibel, så $defs-blokken her falder direkte under components.schemas efter en lille omdøbning. Ingen protoc-gen-openapi-plugin at installere, ingen Buf CLI at sætte op — bare indsæt, redigér, commit.

LLM structured outputs fra et proto

Du vil have OpenAI eller Anthropic til at returnere et typet Order-objekt, der matcher dit eksisterende .proto. Indsæt skemaet, tag $defs/Order-posten og send den som JSON Schema i response_format. Modellen producerer nu output, der laver round-trip gennem din gRPC-service uden manuel coercion.

Reviewe en Protobuf-API-ændring

En backend-kollega tilføjede to fields til Address og omdøbte en enum-værdi. Du vil se, hvordan det påvirker det JSON Schema, din gateway bruger, uden at køre hele codegen-pipelinen. Indsæt det nye .proto, diff skemaet mod din committede kopi, læg en fokuseret review-kommentar på PR'en.

Hyppige spørgsmål

Bliver mit skema sendt nogen steder?

Nej. Parseren og JSON Schema-emitteren kører helt i din browser som JavaScript. Åbn DevTools og kig på Network-fanen mens du indsætter — nul requests. Praktisk når dit skema indeholder interne package-paths, type-navne eller noget, du ikke vil aflevere til en tredjepartstjeneste.

Hvilket JSON Schema-draft sigter outputtet på?

Draft 2020-12, det nuværende publicerede draft. $schema-URI'en på hvert output-dokument er https://json-schema.org/draft/2020-12/schema. Se 2020-12 release notes for hvad der er ændret siden 2019-09. Enhver aktivt vedligeholdt validator (Ajv 8+, jsonschema 4+ til Python, NJsonSchema, Justify til Java) understøtter 2020-12 som standard.

Hvorfor er int64-fields strings, ikke integers?

Fordi det er hvad specifikationen for proto3-JSON-mapping siger, og den har ret. JSON Numbers er IEEE-754-doubles, som mister præcision over 2^53. En rigtig int64 kan bære værdier langt over det loft — order-ID'er, timestamps i nanos, ledger-saldi — så proto3 koder 64-bit heltal som quoterede JSON-strings. Skemaet afspejler det med type: "string", format: "int64" og et numerisk pattern, så en validator stadig afviser "abc". Hvis din server udleverer 64-bit ints som rå JSON Numbers (det gør nogle legacy-gateways), så lav de poster om til { "type": "integer" } i hånden.

Hvorfor er enums strings, ikke integers?

Samme grund — det er proto3's default JSON-encoding. Enums serialiseres som deres værdinavn ("ORDER_STATUS_PAID") frem for det hele wire-tal (2). Det gør JSON-payloads læsbare og skemaet enklere. Heltalsnumrene er ikke i JSON Schema, fordi de er en wire-format-sag, ikke en validerings-sag. Hvis du har en non-default encoder konfigureret til at sende ints, så byt type: "string" ud med type: "integer" på enum-posten.

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

Renderes som { "type": "object", "additionalProperties": <V-schema> }. JSON-objekt-nøgler er altid strings, så en proto-map med en ikke-string-nøgle (f.eks. map<int32, string>) får en description-note, der forklarer, at runtime-nøglerne bliver string-coercet. Værdi-skemaet følger de samme type-mapping-regler som et almindeligt field.

Bliver fields markeret required?

Nej — proto3-fields har altid en default i wire-formatet og er altid til stede i JSON-outputtet (med tomme defaults som "", 0, false, [], {}), så skemaet lister ikke noget under required. Hvis du faktisk vil have at et field er required ved validering, så føj det til en required-array på parent-messaget i hånden. proto3 optional-fields og oneof håndhæves heller ikke som oneOf i outputtet — det er runtime-semantik, som JSON Schema ikke fuldt ud kan udtrykke uden ekstra annotationer.

Hvordan refereres nestede messages?

Hver message og enum hejses op til en flad $defs-blok nøglet efter sit leaf-navn. Field-referencer går via $ref: "#/$defs/MessageName". Fladningen holder dokumentet kompakt og betyder, at dobbelt-nestede typer ikke duplikeres. Hvis to messages i forskellige packages deler et leaf-navn, beholder konverteren den første definition — del konfliktende navne op før du indsætter, hvis det er vigtigt.

Kan jeg stikke det her direkte ind i Ajv?

Ja. ajv.compile(schema) på outputtet virker ud af boksen så snart Ajv er konfigureret til draft 2020-12 (new Ajv2020() fra ajv/dist/2020). $ref-posterne løses internt, fordi alt ligger i samme dokument. Vil du have format-validering (date-time, duration), så tilføj ajv-formats ved siden af.

Relaterede værktøjer

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