1# Encoding 2 3The gRPC API for sending and receiving is based upon *messages*. However, 4messages cannot be transmitted directly over a network; they must first be 5converted into *bytes*. This document describes how gRPC-Go converts messages 6into bytes and vice-versa for the purposes of network transmission. 7 8## Codecs (Serialization and Deserialization) 9 10A `Codec` contains code to serialize a message into a byte slice (`Marshal`) and 11deserialize a byte slice back into a message (`Unmarshal`). `Codec`s are 12registered by name into a global registry maintained in the `encoding` package. 13 14### Implementing a `Codec` 15 16A typical `Codec` will be implemented in its own package with an `init` function 17that registers itself, and is imported anonymously. For example: 18 19```go 20package proto 21 22import "google.golang.org/grpc/encoding" 23 24func init() { 25 encoding.RegisterCodec(protoCodec{}) 26} 27 28// ... implementation of protoCodec ... 29``` 30 31For an example, gRPC's implementation of the `proto` codec can be found in 32[`encoding/proto`](https://godoc.org/google.golang.org/grpc/encoding/proto). 33 34### Using a `Codec` 35 36By default, gRPC registers and uses the "proto" codec, so it is not necessary to 37do this in your own code to send and receive proto messages. To use another 38`Codec` from a client or server: 39 40```go 41package myclient 42 43import _ "path/to/another/codec" 44``` 45 46`Codec`s, by definition, must be symmetric, so the same desired `Codec` should 47be registered in both client and server binaries. 48 49On the client-side, to specify a `Codec` to use for message transmission, the 50`CallOption` `CallContentSubtype` should be used as follows: 51 52```go 53 response, err := myclient.MyCall(ctx, request, grpc.CallContentSubtype("mycodec")) 54``` 55 56As a reminder, all `CallOption`s may be converted into `DialOption`s that become 57the default for all RPCs sent through a client using `grpc.WithDefaultCallOptions`: 58 59```go 60 myclient := grpc.Dial(ctx, target, grpc.WithDefaultCallOptions(grpc.CallContentSubtype("mycodec"))) 61``` 62 63When specified in either of these ways, messages will be encoded using this 64codec and sent along with headers indicating the codec (`content-type` set to 65`application/grpc+<codec name>`). 66 67On the server-side, using a `Codec` is as simple as registering it into the 68global registry (i.e. `import`ing it). If a message is encoded with the content 69sub-type supported by a registered `Codec`, it will be used automatically for 70decoding the request and encoding the response. Otherwise, for 71backward-compatibility reasons, gRPC will attempt to use the "proto" codec. In 72an upcoming change (tracked in [this 73issue](https://github.com/grpc/grpc-go/issues/1824)), such requests will be 74rejected with status code `Unimplemented` instead. 75 76## Compressors (Compression and Decompression) 77 78Sometimes, the resulting serialization of a message is not space-efficient, and 79it may be beneficial to compress this byte stream before transmitting it over 80the network. To facilitate this operation, gRPC supports a mechanism for 81performing compression and decompression. 82 83A `Compressor` contains code to compress and decompress by wrapping `io.Writer`s 84and `io.Reader`s, respectively. (The form of `Compress` and `Decompress` were 85chosen to most closely match Go's standard package 86[implementations](https://golang.org/pkg/compress/) of compressors. Like 87`Codec`s, `Compressor`s are registered by name into a global registry maintained 88in the `encoding` package. 89 90### Implementing a `Compressor` 91 92A typical `Compressor` will be implemented in its own package with an `init` 93function that registers itself, and is imported anonymously. For example: 94 95```go 96package gzip 97 98import "google.golang.org/grpc/encoding" 99 100func init() { 101 encoding.RegisterCompressor(compressor{}) 102} 103 104// ... implementation of compressor ... 105``` 106 107An implementation of a `gzip` compressor can be found in 108[`encoding/gzip`](https://godoc.org/google.golang.org/grpc/encoding/gzip). 109 110### Using a `Compressor` 111 112By default, gRPC does not register or use any compressors. To use a 113`Compressor` from a client or server: 114 115```go 116package myclient 117 118import _ "google.golang.org/grpc/encoding/gzip" 119``` 120 121`Compressor`s, by definition, must be symmetric, so the same desired 122`Compressor` should be registered in both client and server binaries. 123 124On the client-side, to specify a `Compressor` to use for message transmission, 125the `CallOption` `UseCompressor` should be used as follows: 126 127```go 128 response, err := myclient.MyCall(ctx, request, grpc.UseCompressor("gzip")) 129``` 130 131As a reminder, all `CallOption`s may be converted into `DialOption`s that become 132the default for all RPCs sent through a client using `grpc.WithDefaultCallOptions`: 133 134```go 135 myclient := grpc.Dial(ctx, target, grpc.WithDefaultCallOptions(grpc.UseCompresor("gzip"))) 136``` 137 138When specified in either of these ways, messages will be compressed using this 139compressor and sent along with headers indicating the compressor 140(`content-coding` set to `<compressor name>`). 141 142On the server-side, using a `Compressor` is as simple as registering it into the 143global registry (i.e. `import`ing it). If a message is compressed with the 144content coding supported by a registered `Compressor`, it will be used 145automatically for decompressing the request and compressing the response. 146Otherwise, the request will be rejected with status code `Unimplemented`. 147