protobufavrojsonconvertersschema

Generating a Protobuf or Avro Schema from a Real JSON Sample

·6 min read·Converters

Skipping the blank-file problem

Deciding *whether* to move from JSON to Protobuf is a separate question from actually writing the schema — see Protocol Buffers vs JSON: When Should You Switch? for that tradeoff. Once you've decided, the practical next step is usually staring at a blank .proto file and manually transcribing every field from an existing API response. JSONKit's JSON to Protobuf / Avro generator skips that step — paste a real JSON sample, get a starting schema back.

What gets inferred, and what you still need to check

json
{
  "orderId": "ord_9182",
  "total": 129.99,
  "paid": true,
  "items": [{ "sku": "SKU-1", "qty": 2 }]
}
protobuf
syntax = "proto3";

message Order {
  string order_id = 1;
  double total = 2;
  bool paid = 3;
  repeated Items items = 4;
}

message Items {
  string sku = 1;
  int32 qty = 2;
}

Scalar types, nested messages, and repeated fields all infer cleanly from a single example — a string stays a string, a decimal becomes double, a nested object becomes its own message. What a single JSON sample fundamentally *can't* tell you: whether an integer field should be int32 or int64 if your sample value happens to be small right now but could grow past 2^31 later, and what a field typed null in your sample should really be (the generator flags this with a comment rather than guessing). Field numbers are also assigned sequentially in the order they appear — review and lock these in deliberately, since a Protobuf field number can never be reassigned to a different field once real messages using it exist anywhere.

The Avro side of the same tool

Switching the output format to Avro on the same input produces a record schema instead of a .proto message — useful if your target is Kafka, a data lake ingestion pipeline, or another Avro-native system rather than gRPC:

json
{
  "type": "record",
  "name": "Order",
  "fields": [
    { "name": "order_id", "type": "string" },
    { "name": "total", "type": "double" },
    { "name": "paid", "type": "boolean" }
  ]
}

Avro's schema is itself JSON, which makes it directly diffable and reviewable in a normal pull request the way a compiled .proto binary descriptor isn't — a real practical advantage during schema review, independent of Avro vs. Protobuf's other tradeoffs.

After generating: compile it, don't just paste it into production

The generated schema is a draft, not a finished artifact — run it through protoc/buf (Protobuf) or your Avro library's schema validation before treating it as final, and specifically review: field numbering (Protobuf), any field the tool flagged as inferred-from-null, and whether an integer field's size assumption (int32 vs int64) matches what the field will actually hold in production, not just in your one sample.

Frequently asked questions

Yes — paste a JSON array and the generator uses the first element as the sample, since a repeated top-level array isn't itself representable as a single Protobuf message or Avro record; the schema describes one record's shape.

Just the schema (.proto text or Avro's JSON schema) — compiling that into language-specific types is a separate step done by protoc/buf for Protobuf, or your Avro library's code generator (e.g. avro-tools for Java) for Avro.

Because a single example genuinely doesn't contain enough information — a field that's null in your one sample could be "always null" or "sometimes null, sometimes a string" in the real data, and guessing wrong silently would be worse than flagging it for you to fill in from your actual API contract.

No — if you already have an OpenAPI/JSON Schema definition (not just a sample response), that's a more authoritative source than inferring from one example, since it captures the *intended* contract including nullability and required fields rather than just what one sample happened to contain. This tool is specifically for the common case of only having a real response, not a formal spec.

Try JSONKit — JSON Developer Tools

Format, validate, convert and diff JSON. Instant, accurate and 100% private.