Skip to content

JSON Schema to Protobuf Definitions — Numio

Turns an object-type JSON Schema into a proto2 message definition. Fields are numbered in property order; required properties become "required", others "optional", arrays "repeated", and nested objects become nested messages with a field that uses them.

You have a JSON Schema for an event and want a first draft of a .proto message to edit for a gRPC or Kafka pipeline.

JSON Schema

When to use it

  • You have a JSON Schema for an event and want a first draft of a .proto message to edit for a gRPC or Kafka pipeline.
  • You want to check how the scalar fields of an existing schema would map to protobuf types before writing the message yourself.

How to use

  1. Paste a JSON Schema with "type": "object" at the root. The message name comes from "title" in PascalCase (or a "name" key); without either it is Root.
  2. The conversion runs in your browser; there are no settings.
  3. Copy the proto2 text from the Protobuf panel and review the types before using it in a .proto file.

JSON Schema

{
  "title": "Order",
  "type": "object",
  "properties": {
    "id": { "type": "string" },
    "quantity": { "type": "integer" },
    "price": { "type": "number" },
    "paid": { "type": "boolean" },
    "tags": { "type": "array", "items": { "type": "string" } },
    "shipping": { "type": "object", "properties": { "city": { "type": "string" } } }
  },
  "required": ["id", "quantity"]
}

Protocol Buffers (proto2)

syntax = "proto2";

message Order {
  message Shipping {
    optional string city = 1;
  }

  required string id = 1;
  required int32 quantity = 2;
  optional double price = 3;
  optional bool paid = 4;
  repeated string tags = 5;
  optional Shipping shipping = 6;
}

Details and limitations

The conversion runs in your browser with the site's own converter; the schema is not sent to a server.

integer maps to int32 (int64 with format int64 or bounds outside the 32-bit range), number to double (float with format float) and boolean to bool. Array item types are mapped the same way.

String enums become a nested enum with prefixed UPPER_SNAKE values, additionalProperties schemas become map<string, T>, and local $ref to definitions or $defs points to a top-level message.

Arrays of arrays, oneOf/anyOf with several non-null branches and untyped properties fall back to string. A $ref to another file is reported as an error.

FAQ

Does it generate proto3?

No. The output always starts with syntax = "proto2" and uses required/optional labels.

How is the message name chosen?

From the root "title" converted to PascalCase, so "Example Schema" becomes ExampleSchema, or from a "name" key. Without either the message is called Root. Nested messages and enums are named after their property.

How are nullable fields like ["string", "null"] handled?

The null part is dropped and the field uses the remaining type, for example optional double height for ["number", "null"]. proto2 optional fields can already be absent.

Is my schema uploaded?

No. This page converts the schema in the browser and does not call a server API.

Specifications and references