GRPC Protobuf 3 Support
Summary
AMF supports APIs defined using Protocol Buffers version 3 (proto3) syntax for gRPC services.
AMF only supports APIs that start with syntax = "proto3";. Other versions such as proto2 or the newer edition = "2023"; will be parsed as an ExternalFragment.
To get started with GRPC support you should use the GRPCConfiguration
AMF GRPC Processing Stack
AMF provides comprehensive support for Protobuf 3 APIs through a multi-stage processing pipeline:
Syntactic Parsing
Protobuf 3 APIs are parsed using ANTLR using this version of the grammar defined in the amf-antlr-ast repository.
Semantic Parsing
Semantic parsing is performed by AMF using the GRPCConfiguration, which transforms the syntactic AST into the AMF model.
Transformation / Resolution
AMF applies transformation and resolution steps to produce the canonical model representation.
Validation
Validation is performed using two complementary approaches:
- Standard
protocvalidator for protocol buffer compliance - AMF-specific validations for additional constraints
Parsing Support
Supported Syntax
AMF supports parsing of .proto files that declare Protobuf version 3:
syntax = "proto3";
Files without this declaration or using other versions will not be processed by the GRPCConfiguration and will instead be parsed as an ExternalFragment.
Package Requirement
AMF requires that APIs define a package property. If no package is defined, AMF will add a default one.
syntax = "proto3";
package myservice.v1;
service MyService {
rpc GetData (Request) returns (Response);
}
Known Limitations
Optional Field Support
The current GRPC grammar in AMF does not support the optional keyword for fields.
The optional property was originally removed when proto3 first launched (making all fields "implicit" where 0/empty was the default), but was reintroduced in Protobuf v3.15 (released in early 2021).
The AMF grammar needs to be updated to support this feature.
Validation Support
The GRPCConfiguration provides validation through two layers:
Standard Protoc Validation
All standard Protocol Buffer validations are enforced through integration with the protoc validator.
AMF-Specific Validations
In addition to protoc validations, AMF enforces the following requirements:
- Package declaration: APIs must define a
packageproperty, or AMF will add a default one
Mappings
Although a Protobuf 3 is not exactly an API, it shares similar concepts, and we will map it to the AMF models as follows:
| gRPC/Protobuf Concept | AMF Model Object | Specific object fields |
|---|---|---|
| Service | EndPoint | |
| Service rpc | Operation | the input is a Request and the output a Response |
| Message | NodeShape | each field, map or oneof is contained in a PropertyShape where the range property contains the value (see below for each one) |
| Message Field | PropertyShape | it's options are mapped to the customDomainProperties property, the serializationOrder contains de number, and the range property contains the value |
| Message one of | AnyShape | PropertyShape that contains an AnyShape in it's range and the oneof values are inside the xone property of that shape |
| Message enum | ScalarShape | PropertyShape that contains a ScalarShape where values property contains the enum values, and it's options are saved inside the customDomainProperties property |
| Option | DomainExtension |
The BaseUnit that results from parsing is a Document with a declares property that will contain all the messages and
enums declared.
The package property of the GRPC/Protobuf API is mapped to the package property of the AMF Document.
The Document also has an encodes property that contains the WebApi that encodes the Protobuf 3 API.
Operation Methods
In gRPC, RPC methods can use streaming for requests and/or responses. AMF maps these different streaming patterns to specific operation methods based on the communication pattern they represent.
The operation method is determined by whether the request and response use streaming:
| Request Type | Response Type | AMF Operation Method | Description |
|---|---|---|---|
| Unary (no stream) | Unary (no stream) | post | Client sends a single request and receives a single response (standard request-response) |
| Stream | Unary (no stream) | publish | Client sends a stream of messages and receives a single response (client streaming) |
| Unary (no stream) | Stream | subscribe | Client sends a single request and receives a stream of responses (server streaming) |
| Stream | Stream | pubsub | Client and server both send streams of messages (bidirectional streaming) |
Example
The following protobuf service demonstrates all four operation methods:
// Service definition maps to EndPoint in AMF model
service Greeter {
option deprecated = false;
// Unary RPC: single request → single response (maps to 'post')
rpc PostExample (RequestMessage) returns (ResponseMessage) {
option deprecated = true;
}
// Client streaming: stream of requests → single response (maps to 'publish')
rpc PublishExample (stream RequestMessage) returns (ResponseMessage) {}
// Server streaming: single request → stream of responses (maps to 'subscribe')
rpc SubscribeExample (RequestMessage) returns (stream ResponseMessage) {}
// Bidirectional streaming: stream of requests → stream of responses (maps to 'pubsub')
rpc PubSubExample (stream RequestMessage) returns (stream ResponseMessage) {}
}