Protobuf schemas in AsyncAPI
A Protocol Buffers message can be an AsyncAPI payload. Wrap the .proto source in a Multi Format Schema Object with schemaFormat: application/vnd.google.protobuf;version=3 (or version=2 for proto2), and put the source text in schema.
Unlike Avro, the schema is a string: the content of a .proto file, not a JSON or YAML object.
AsyncAPI 3.0
Section titled “AsyncAPI 3.0”asyncapi: 3.0.0info: title: Orders version: 1.0.0channels: orderPlaced: address: orders.placed messages: orderPlaced: $ref: '#/components/messages/orderPlaced'operations: onOrderPlaced: action: receive channel: $ref: '#/channels/orderPlaced'components: messages: orderPlaced: contentType: application/x-protobuf payload: schemaFormat: application/vnd.google.protobuf;version=3 schema: | syntax = "proto3";
package example.orders;
message OrderPlaced { string order_id = 1; string customer_id = 2; repeated LineItem items = 3; int64 placed_at = 4; // Unix epoch, milliseconds }
message LineItem { string sku = 1; int32 quantity = 2; }When the source holds several messages, the payload is the one no other message uses as a field type: here OrderPlaced, because LineItem is a field of it. If more than one message qualifies, mark the payload with a // @RootNode comment, or parsing fails. Leading comments become descriptions.
AsyncAPI 2.x
Section titled “AsyncAPI 2.x”schemaFormat belongs to the message, and the .proto text goes in payload:
asyncapi: 2.6.0info: title: Orders version: 1.0.0channels: orders.placed: subscribe: message: schemaFormat: application/vnd.google.protobuf;version=3 contentType: application/x-protobuf payload: | syntax = "proto3"; message OrderPlaced { string order_id = 1; }“Unsupported schemaFormat” errors
Section titled ““Unsupported schemaFormat” errors”AsyncAPI tools must understand JSON Schema and AsyncAPI schemas; every other format is a plugin. Protobuf support lives in @asyncapi/protobuf-schema-parser. AsyncAPI CLI and Studio include it. If another validator or generator reports that application/vnd.google.protobuf is unsupported, it runs the parser without that plugin. With the JavaScript parser, register it yourself:
import { Parser } from '@asyncapi/parser'import { ProtoBuffSchemaParser } from '@asyncapi/protobuf-schema-parser'
const parser = new Parser()parser.registerSchemaParser(ProtoBuffSchemaParser())const { document, diagnostics } = await parser.parse(asyncapiYaml)JSON Schema validators that only check the document’s structure, such as the registry schemas, accept any string in schema for Protobuf; they don’t compile it.
Related
Section titled “Related”Questions
Can I reference a .proto file instead of inlining it?
Not with the AsyncAPI Protobuf parser: it supports neither $ref to a .proto file nor import, except the bundled google/protobuf/*, google/type/* and validation definitions. Inline the source; many teams generate the inline text from their .proto files at build time.
Which contentType should Protobuf messages have?
application/x-protobuf and application/protobuf are both in use. Pick the one your producers set in message headers and use it consistently.
Does AsyncAPI describe gRPC services?
Not directly. AsyncAPI describes message-driven APIs: channels, operations and messages. It can describe Protobuf messages flowing through Kafka, MQTT, NATS or WebSocket channels; gRPC services are described by their .proto service definitions.