Raw Encoded Buffers (Partial Decoding)

By default a request message is protobuf-encoded before it is sent and the response is decoded before it is returned. Either side can instead be left as a raw, already-encoded protobuf payload — a Vector{UInt8} holding just the message body, with the 5-byte gRPC framing still added and stripped for you. This is useful for forwarding bytes you already hold, or for partially decoding a large response and reading only the fields you need.

On the request side, pass a Vector{UInt8} in place of the typed message, whether as the call argument or to put!:

using ProtoBufchan = gRPCChannel("localhost", 8001)io = IOBuffer(); encode(ProtoEncoder(io), TestRequest(10, UInt64[]))raw_request = take!(io)response = TestService.TestRPC(chan, raw_request)   # typed response

On the response side, request raw bytes by passing Vector{UInt8} as an extra argument to the call, or to fetch / take!:

# Unary: receive the response undecodedraw = TestService.TestRPC(chan, TestRequest(10, UInt64[]), Vector{UInt8})response = decode(ProtoDecoder(IOBuffer(raw)), TestResponse)# Server streaming: take each response as raw bytes (this request asks for 10)rpc = TestService.TestServerStreamRPC(chan, TestRequest(10, UInt64[]))for _ in 1:10    raw = take!(rpc, Vector{UInt8})    # decode(ProtoDecoder(IOBuffer(raw)), TestResponse)end

A raw response shares the received message's memory rather than copying it (on Julia 1.11 and later). fetch does not consume the response, so an asynchronous call can be fetched again, raw or decoded, and every raw fetch returns the same bytes. Modifying them therefore changes what later fetches of the call return; copy them first if you need to change them and fetch again. On a response stream, take!(rpc, Vector{UInt8}) removes the response and hands its buffer over.

The two sides are independent, so either or both may be raw. The same mechanism is covered in more depth for the legacy API.