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