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 |
|
Purpose | Protobuf payload encoding and validation for AsyncAPI messages |
Content types |
|
Schema format |
|
Used with |
|
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: jsonThe 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:
The
protoparameter oncontentType, for examplecontentType: application/vnd.google.protobuf; proto=orders.OrderCreated'.The
x-drift-proto-messageextension on the payload object.The AsyncAPI message name or ID. Drift matches it exactly, then with the package name, then in PascalCase. For example, the message ID
orderCreatedmatchesorders.OrderCreated.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 |
|---|---|
| Captures the message your service publishes, decodes it with the schema, checks field types, and compares the result with |
| Encodes |
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
.protofiles by path.importstatements that reference other.protofiles are not supported. Well-known Google types, such asgoogle.protobuf.Timestamp, are supported.Expected payloads and
parameters.payloadmust 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 | The plugin is not installed. Run |
Error listing candidate message names | Drift cannot tell which message is the payload. Add |
Expected field reported as missing, but the service sends it | The expected payload uses a camelCase name. Use the field name from the |
Payload handled as JSON instead of protobuf | The message |
Schema compile error mentioning an import | The schema imports another |
See Debugging Test Cases.
See Also
AsyncAPI Plugin
gRPC Plugin
Managing Component