Protobuf Plugin

The Protobuf plugin lets Drift encode and validate Protocol Buffers (protobuf) message payloads. Use it with the AsyncAPI plugin to verify message-based APIs whose messages use a protobuf binary payload.

The plugin compiles the .proto schema embedded in your AsyncAPI document. You do not need protoc or any generated code.

Property

Value

Plugin name

protobuf

Purpose

Protobuf payload encoding and validation for AsyncAPI messages

Content types

application/vnd.google.protobuf, application/protobuf, application/x-protobuf, application/x-google-protobuf

Schema format

application/vnd.google.protobuf;version=3

Used with

asyncapi, a transport plugin (kafka or aws-messaging), and json

Tier

Optional

Note

To test gRPC services, use the gRPC Plugin. The Protobuf plugin handles message payloads in AsyncAPI documents only.

Enabling the Plugin

The Protobuf plugin is an optional component. Install it before you use it:

drift component install protobuf

Then add it to the plugins section of your test case file, together with the AsyncAPI plugin, a transport plugin, and the JSON plugin:

    plugins:
      - name: asyncapi
      - name: kafka
      - name: protobuf
      - name: json

The JSON plugin is required because Drift always validates message headers as JSON.

The Protobuf plugin activates for any message whose contentType is one of the supported protobuf content types.

Describing the Payload in Your AsyncAPI Document

Declare the payload with an AsyncAPI multi-format schema. Set schemaFormat to the protobuf schema format, and embed the .proto source as a string in schema:

 components:
      messages:
        orderCreated:
          contentType: application/vnd.google.protobuf
          payload:
            schemaFormat: application/vnd.google.protobuf;version=3
            schema: |
              syntax = "proto3";
              package orders;

              message Address {
                string street = 1;
                string city   = 2;
              }

              message OrderCreated {
                string order_id    = 1;
                string customer_id = 2;
                string status      = 3;
                Address address    = 4;
              }

Both contentType and schemaFormat with schema are required. contentType selects the Protobuf plugin, and schema gives Drift the message definition. Define every message type the payload uses in the same schema. AsyncAPI does not allow $ref inside a protobuf schema.

Selecting the Payload Message

When the schema defines more than one message, Drift chooses the payload message in this order:

  1. The proto parameter on contentType, for example contentType: application/vnd.google.protobuf; proto=orders.OrderCreated'.

  2. The x-drift-proto-message extension on the payload object.

  3. The AsyncAPI message name or ID. Drift matches it exactly, then with the package name, then in PascalCase. For example, the message ID orderCreated matches orders.OrderCreated.

  4. The only top-level message, if the schema defines exactly one.

If none of these match, Drift reports an error that lists every message in the schema.

In most cases, naming the AsyncAPI message after the protobuf message is enough.

Writing Expected Payloads

Use the protobuf field names from your .proto file, which are usually snake_case. Do not use the camelCase names that protobuf generates for JSON.

    operations:
      SendOrderCreated_Observe:
        target: orders-api:sendOrderCreated:orderCreated
        parameters:
          correlation-id: order-created-001
        trigger:
          # ...
        expected:
          headers:
            correlation-id: ${parameters.correlation-id}
          payload:
            order_id: ORD-100        # Proto field name, not orderId
            customer_id: CUST-9
            status: created
            address:
              street: "123 Main St"
              city: "Anytown"

The same rule applies to parameters.payload when Drift sends a message to your service(action: receive).

Validation Behavior

How Drift uses the plugin depends on the operation's action:

Action

What Drift does

send

Captures the message your service publishes, decodes it with the schema, checks field types, and compares the result with expected.payload

receive

Encodes parameters.payload as protobuf binary using the schema, and publishes it for your service to consume.

When Drift compares payloads:

  • Drift checks only the fields in expected.payload. Extra fields in the actual message are allowed.

  • Drift reports a mismatch for any expected field that is missing from the actual message.

  • Drift treats proto3 default values (empty string, 0, false) as absent when the expected value is also the default value.

  • Values must match exactly. Drift does not support matching rules, such as type or regex matching, for protobuf payloads.

Configuration

To make the plugin handle additional content types, add them in drift.config.toml:

 [plugin_config.protobuf]
    content_types = ["application/octet-stream"]

Use this setting with care. A broad content type, such as application/octet-stream, can cause the Protobuf plugin to handle payloads intended for another plugin.

  [plugin_config.protobuf]
    content_types = ["application/octet-stream"]

Use this setting with care. A broad content type, such as application/octet-stream, can cause the Protobuf plugin to handle payloads intended for another plugin.

Limitations

  • The schema must be embedded in the AsyncAPI document. Drift does not load .proto files by path.

  • import statements that reference other .proto files are not supported. Well-known Google types, such as google.protobuf.Timestamp, are supported.

  • Expected payloads and parameters.payload must use proto field names, not camelCase JSON names.

  • Drift does not support matching rules for protobuf payloads.

  • Proto2 support is partial. Drift applies proto3 rules to required fields and default values.

Troubleshooting

Symptom

Likely cause

Don't know how to resolve plugin protobuf

The plugin is not installed. Run drift component install protobuf

Error listing candidate message names

Drift cannot tell which message is the payload. Add proto=<package.Message> to contentType, or add x-drift-proto-message to the payload.

Expected field reported as missing, but the service sends it

The expected payload uses a camelCase name. Use the field name from the .proto file.

Payload handled as JSON instead of protobuf

The message contentType is missing or is not a supported protobuf content type.

Schema compile error mentioning an import

The schema imports another .proto file. Copy the imported messages into the embedded schema.

See Debugging Test Cases.

See Also

AsyncAPI Plugin

gRPC Plugin

Managing Component

Publication date: