# Encoding

The gRPC API for sending and receiving is based upon *messages*.  However,
messages cannot be transmitted directly over a network; they must first be
converted into *bytes*.  This document describes how gRPC-Go converts messages
into bytes and vice-versa for the purposes of network transmission.

## Codecs (Serialization and Deserialization)

A `Codec` contains code to serialize a message into a byte slice (`Marshal`) and
deserialize a byte slice back into a message (`Unmarshal`).  `Codec`s are
registered by name into a global registry maintained in the `encoding` package.

### Implementing a `Codec`

A typical `Codec` will be implemented in its own package with an `init` function
that registers itself, and is imported anonymously.  For example:

```go
package proto

import "google.golang.org/grpc/encoding"

func init() {
	encoding.RegisterCodec(protoCodec{})
}

// ... implementation of protoCodec ...
```

For an example, gRPC's implementation of the `proto` codec can be found in
[`encoding/proto`](https://godoc.org/google.golang.org/grpc/encoding/proto).

### Using a `Codec`

By default, gRPC registers and uses the "proto" codec, so it is not necessary to
do this in your own code to send and receive proto messages.  To use another
`Codec` from a client or server:

```go
package myclient

import _ "path/to/another/codec"
```

`Codec`s, by definition, must be symmetric, so the same desired `Codec` should
be registered in both client and server binaries.

On the client-side, to specify a `Codec` to use for message transmission, the
`CallOption` `CallContentSubtype` should be used as follows:

```go
	response, err := myclient.MyCall(ctx, request, grpc.CallContentSubtype("mycodec"))
```

As a reminder, all `CallOption`s may be converted into `DialOption`s that become
the default for all RPCs sent through a client using `grpc.WithDefaultCallOptions`:

```go
	myclient := grpc.Dial(ctx, target, grpc.WithDefaultCallOptions(grpc.CallContentSubtype("mycodec")))
```

When specified in either of these ways, messages will be encoded using this
codec and sent along with headers indicating the codec (`content-type` set to
`application/grpc+<codec name>`).

On the server-side, using a `Codec` is as simple as registering it into the
global registry (i.e. `import`ing it).  If a message is encoded with the content
sub-type supported by a registered `Codec`, it will be used automatically for
decoding the request and encoding the response.  Otherwise, for
backward-compatibility reasons, gRPC will attempt to use the "proto" codec.  In
an upcoming change (tracked in [this
issue](https://github.com/grpc/grpc-go/issues/1824)), such requests will be
rejected with status code `Unimplemented` instead.

## Compressors (Compression and Decompression)

Sometimes, the resulting serialization of a message is not space-efficient, and
it may be beneficial to compress this byte stream before transmitting it over
the network.  To facilitate this operation, gRPC supports a mechanism for
performing compression and decompression.

A `Compressor` contains code to compress and decompress by wrapping `io.Writer`s
and `io.Reader`s, respectively.  (The form of `Compress` and `Decompress` were
chosen to most closely match Go's standard package
[implementations](https://golang.org/pkg/compress/) of compressors.  Like
`Codec`s, `Compressor`s are registered by name into a global registry maintained
in the `encoding` package.

### Implementing a `Compressor`

A typical `Compressor` will be implemented in its own package with an `init`
function that registers itself, and is imported anonymously.  For example:

```go
package gzip

import "google.golang.org/grpc/encoding"

func init() {
	encoding.RegisterCompressor(compressor{})
}

// ... implementation of compressor ...
```

An implementation of a `gzip` compressor can be found in
[`encoding/gzip`](https://godoc.org/google.golang.org/grpc/encoding/gzip).

### Using a `Compressor`

By default, gRPC does not register or use any compressors.  To use a
`Compressor` from a client or server:

```go
package myclient

import _ "google.golang.org/grpc/encoding/gzip"
```

`Compressor`s, by definition, must be symmetric, so the same desired
`Compressor` should be registered in both client and server binaries.

On the client-side, to specify a `Compressor` to use for message transmission,
the `CallOption` `UseCompressor` should be used as follows:

```go
	response, err := myclient.MyCall(ctx, request, grpc.UseCompressor("gzip"))
```

As a reminder, all `CallOption`s may be converted into `DialOption`s that become
the default for all RPCs sent through a client using `grpc.WithDefaultCallOptions`:

```go
	myclient := grpc.Dial(ctx, target, grpc.WithDefaultCallOptions(grpc.UseCompressor("gzip")))
```

When specified in either of these ways, messages will be compressed using this
compressor and sent along with headers indicating the compressor
(`content-coding` set to `<compressor name>`).

On the server-side, using a `Compressor` is as simple as registering it into the
global registry (i.e. `import`ing it).  If a message is compressed with the
content coding supported by a registered `Compressor`, it will be used
automatically for decompressing the request and compressing the response.
Otherwise, the request will be rejected with status code `Unimplemented`.
