Kinoko's TIL Log

gRPC Metadata vs Proto Fields for HTTP Headers

The Point

When converting a partner’s HTTP API to proto, standard HTTP headers (Content-Length, etc.) should not go into the message – the gRPC framework handles them automatically. Custom headers (like amzn-request-id) go either in a response message field or in gRPC trailing metadata, depending on their purpose.

Explanation

Background: converting an Excel API spec to proto

The partner’s API doc (Japanese-style Excel format) lists HTTP response headers and custom headers together. When converting to proto, you need to decide which ones belong in the message and which do not.

Standard HTTP Headers – do not put in proto

Transport-layer headers like Content-Length, Content-Type, and Transfer-Encoding are handled by the gRPC framework:

Custom Headers (e.g. amzn-request-id) – two approaches

ApproachProsConsBest for
Response message fieldSimple, consumer reads directlyHeader semantics flattened into messageIDs with business/tracing meaning
gRPC Trailing MetadataFollows gRPC idiom, does not pollute messageConsumer needs to use the metadata APIPure infra use (rate limit, etc.)

Go server-side trailing metadata example

 1import "google.golang.org/grpc/metadata"
 2
 3func (s *Server) GetOrder(ctx context.Context, req *pb.GetOrderRequest) (*pb.GetOrderResponse, error) {
 4    // ... call partner API ...
 5
 6    // Put amzn-request-id in trailing metadata
 7    trailer := metadata.Pairs("amzn-request-id", partnerResp.Header.Get("amzn-request-id"))
 8    grpc.SetTrailer(ctx, trailer)
 9
10    return &pb.GetOrderResponse{Order: order}, nil
11}

Add proto comments to preserve traceability

Even if you do not put all headers into the message, you can document the mapping in proto comments for future reference:

1message GetOrderResponse {
2  // Maps to amzn-request-id response header in partner API.
3  // Passed as gRPC trailing metadata, not as a message field.
4  Order order = 1;
5}
6
7// Note: Standard HTTP headers (Content-Length, Content-Type) are intentionally
8// omitted  handled by gRPC framework automatically.

Knowledge Sugar

The “shallow mapping first” logic from a colleague

Map all fields first for traceability, then prune later. This makes sense from a traceability perspective, but once a proto is published there is a risk of breaking changes. A better compromise is to document the mapping in comments rather than putting every header into the message.

What is gRPC Metadata?

gRPC metadata is a set of key-value pairs, equivalent to HTTP headers in the gRPC world. It comes in two flavors:

#grpc #til

← Back to Main Page