Req.Steps (req v0.8.0-rc.0)

Copy Markdown View Source

A collection of built-in steps.

Req is composed of:

See also step modules:

Summary

Request Steps

Compresses the request body.

Encodes the request body.

Signs request with AWS Signature Version 4.

Sets base URL for all requests.

Adds params to request query string.

Uses a templated request path.

Sets the "Range" request header.

Sets the user-agent header.

Request Steps

compress_body(request)

Compresses the request body.

Not supported with body: req_body_fun.

Request Options

  • :compress_body - if set to true, compresses the request body using gzip. Defaults to false.

encode_body(request)

Encodes the request body.

Request Options

  • :form - if set, encodes the request body as application/x-www-form-urlencoded (using URI.encode_query/1).

  • :form_multipart - if set, encodes the request body as multipart/form-data.

    It accepts name / value pairs. value can be one of:

    • integer (automatically encoded as string)

    • iodata

    • File.Stream

    • Enumerable

    • {value, options} tuple.

      value can be any of the values mentioned above.

      Supported options are: :filename, :content_type, and :size.

      When value is an Enumerable, option :size can be set with the binary size of the value. The size will be used to calculate and send the content-length header which might be required for some servers. There is no need to pass :size for integer, iodata, and File.Stream values as it's automatically calculated.

  • :json - if set, encodes the request body as JSON (using JSON.encode_to_iodata!/1), sets the accept header to application/json, and the content-type header to application/json.

When the request has the default HTTP method, GET, and the request body is set, this step automatically changes HTTP method to POST.

Examples

Encoding form (application/x-www-form-urlencoded):

iex> Req.post!("https://httpbingo.org/anything", form: [a: 1]).body["form"]
%{"a" => ["1"]}

Encoding form (multipart/form-data):

iex> fields = [a: 1, b: {"2", filename: "b.txt"}]
iex> resp = Req.post!("https://httpbingo.org/anything", form_multipart: fields)
iex> resp.body["form"]
%{"a" => ["1"]}
iex> resp.body["files"]
%{"b" => ["2"]}

Encoding streaming form (multipart/form-data):

iex> stream = Stream.cycle(["abc"]) |> Stream.take(3)
iex> fields = [file: {stream, filename: "b.txt"}]
iex> resp = Req.post!("https://httpbingo.org/anything", form_multipart: fields)
iex> resp.body["files"]
%{"file" => ["abcabcabc"]}

# with explicit :size
iex> stream = Stream.cycle(["abc"]) |> Stream.take(3)
iex> fields = [file: {stream, filename: "b.txt", size: 9}]
iex> resp = Req.post!("https://httpbingo.org/anything", form_multipart: fields)
iex> resp.body["files"]
%{"file" => ["abcabcabc"]}

Encoding JSON:

iex> Req.post!("https://httpbingo.org/post", json: %{a: 1}).body["json"]
%{"a" => 1}

Automatically change GET to POST when body is set:

iex> Req.request!("https://httpbingo.org/post", json: %{a: 1}).body["json"]
%{"a" => 1}

put_aws_sigv4(request)

Signs request with AWS Signature Version 4.

Request Options

  • :aws_sigv4 - if set, the AWS options to sign request:

    • :access_key_id - the AWS access key id.

    • :secret_access_key - the AWS secret access key.

    • :token - if set, the AWS security token, for example returned from AWS STS.

    • :service - the AWS service. We try to automatically detect the service (e.g. s3.amazonaws.com host sets service to :s3)

    • :region - the AWS region. Defaults to "us-east-1".

    • :datetime - the request datetime, defaults to DateTime.utc_now(:second).

    Additionally, it can be an {mod, fun, args} tuple that returns the above options.

Examples

iex> req =
...>   Req.new(
...>     base_url: "https://s3.amazonaws.com",
...>     aws_sigv4: [
...>       access_key_id: System.get_env("AWS_ACCESS_KEY_ID"),
...>       secret_access_key: System.get_env("AWS_SECRET_ACCESS_KEY")
...>     ]
...>   )
iex>
iex> %{status: 200} = Req.put!(req, url: "/bucket1/key1", body: "Hello, World!")
iex> resp = Req.get!(req, url: "/bucket1/key1").body
"Hello, World!"

Request body streaming also works though content-length header must be explicitly set:

iex> path = "a.txt"
iex> File.write!(path, String.duplicate("a", 100_000))
iex> size = File.stat!(path).size
iex> chunk_size = 10 * 1024
iex> stream = File.stream!(path, chunk_size)
iex> %{status: 200} = Req.put!(req, url: "/bucket1/key1", headers: [content_length: size], body: stream)
iex> byte_size(Req.get!(req, url: "/bucket1/key1").body)
100_000

put_base_url(request)

Sets base URL for all requests.

Request Options

  • :base_url - if set, the request URL is merged with this base URL.

    The base url can be a string, a %URI{} struct, a 0-arity function, or a {mod, fun, args} tuple describing a function to call.

Examples

iex> req = Req.new(base_url: "https://httpbingo.org")
iex> Req.get!(req, url: "/status/200").status
200
iex> Req.get!(req, url: "/status/201").status
201

put_params(request)

Adds params to request query string.

Request Options

  • :params - params to add to the request query string. Defaults to [].

Examples

iex> Req.get!("https://httpbingo.org/anything/query", params: [x: 1, y: 2]).body["args"]
%{"x" => ["1"], "y" => ["2"]}

put_path_params(request)

Uses a templated request path.

By default, params in the URL path are expressed as strings prefixed with :. For example, :code in https://httpbingo.org/status/:code. If you want to use the {code} syntax, set path_params_style: :curly. Param names must start with a letter and can contain letters, digits, and underscores; this is true both for :colon_params as well as {curly_params}.

Path params are replaced in the request URL path. The path params are specified as a keyword list of parameter names and values, as in the examples below. The values of the parameters are converted to strings using the String.Chars protocol (to_string/1).

Request Options

  • :path_params - if set, params to add to the templated path. Defaults to nil.

  • :path_params_style (available since v0.5.1) - how path params are expressed. Can be one of:

    • :colon - (default) for Plug-style parameters, such as :code in https://httpbingo.org/status/:code.

    • :curly - for OpenAPI-style parameters, such as {code} in https://httpbingo.org/status/{code}.

Examples

iex> Req.get!("https://httpbingo.org/status/:code", path_params: [code: 201]).status
201

iex> Req.get!("https://httpbingo.org/status/{code}", path_params: [code: 201], path_params_style: :curly).status
201

put_range(request)

Sets the "Range" request header.

Request Options

  • :range - can be one of the following:

    • a string - returned as is

    • a first..last range - converted to "bytes=<first>-<last>"

Examples

iex> response = Req.get!("https://httpbingo.org/range/100", range: 0..3)
iex> response.status
206
iex> response.body
"abcd"
iex> Req.Response.get_header(response, "content-range")
["bytes 0-3/100"]

put_user_agent(request)

Sets the user-agent header.

Request Options

  • :user_agent - sets the user-agent header. Defaults to "req/0.8.0-rc.0".

Examples

iex> Req.get!("https://httpbingo.org/user-agent").body
%{"user-agent" => "req/0.8.0-rc.0"}

iex> Req.get!("https://httpbingo.org/user-agent", user_agent: "foo").body
%{"user-agent" => "foo"}