# `Req.Decode`
[🔗](https://github.com/wojtekmach/req/blob/v0.8.0-rc.0/lib/req/decode.ex#L1)

Decodes response body based on the detected format.

To decode other formats, or to add support for custom ones, use the `:decoders` option.

## Built-in decoders

| Format               | Decoder                              | Enabled | Streaming Decoding |
| -------------------- | ------------------------------------ | ------- | ------------------ |
| `:json`, `:json_api` | `Req.JSON`                           | ✓       |                    |
| `:ndjson`            | `Req.NDJSON`                         | ✓       | ✓                  |
| `:sse`               | `Req.SSE`                            | ✓       | ✓                  |
| `:zip`               | `Req.ZIP`                            |         |                    |
| `:tar`, `:tgz`       | `Req.Tar`                            |         |                    |
| `:gz`                | `Req.Gzip`                           |         | ✓                  |
| `:zst`               | `Req.Zstd` (requires Erlang/OTP 28+) |         | ✓                  |
| `:csv`               | `Req.CSV` (requires [nimble_csv])    |         |                    |

The format is determined by the response `content-type` header. See `MIME` for registering
content-type/format mapping.

> #### Decompression Bombs {: .warning}
>
> The archive and compression decoders (`:zip`, `:tar`, `:tgz`, `:gz`, and `:zst`) decompress
> the whole response body into memory with no size limit, so a small response can expand to
> many gigabytes. For this reason they are **not** enabled by default; only opt into them via
> the `:decoders` option for endpoints you trust.

## Request Options

  * `:decoders` - the list of decoders to use. Defaults to
    `[:json, :json_api, :ndjson, :sse]`.

    Each element is either:

      * a format (atom) handled by a [built-in decoder](#module-built-in-decoders),
        e.g. `:json` or `:zip`;

      * a `{format, decoder}` or `{content_type, decoder}` tuple, where `format` is an atom e.g.:
        `:json`, `content_type` is a binary e.g.: `application/x-amz-json-1.0`, and `decoder` is
        one of:

          * another format (atom), to reuse a built-in decoder, e.g. `decoders: [json5: :json]`.

          * a 1-arity function that returns `{:ok, term}` or `{:error, exception}`, e.g.:

                decoders: [{"text/calendar", &{:ok, ICal.from_ics(&1)}}]

    Setting `:decoders` replaces the default, so include `:json` if you still want JSON decoded:

        # handles json, zip, and tar:
        Req.new(decoders: [:json, :zip, :tar])

    Set `:decoders` to `false` to disable all decoding, including JSON.

  * `:decode_body` - if set to `false`, disables automatic response body decoding.
    Defaults to `true`.

  * `:raw` - if set to `true`, disables response body decoding. Defaults to `false`.

    Note: setting `raw: true` also disables response body decompression.

## Examples

Decode JSON:

    iex> response = Req.get!("https://httpbingo.org/json")
    ...> response.body["slideshow"]["title"]
    "Sample Slide Show"

Decode a ZIP archive (opt-in):

    iex> response = Req.get!("https://example.com/archive.zip", decoders: [:zip])
    ...> response.body["file.txt"]
    "contents"

[nimble_csv]: https://hex.pm/packages/nimble_csv
[server_sent_events]: https://hex.pm/packages/server_sent_events

---

*Consult [api-reference.md](api-reference.md) for complete listing*
