View Source Req (req v0.4.14)
The high-level API.
Req is composed of three main pieces:
Req- the high-level API (you're here!)Req.Request- the low-level API and the request structReq.Steps- the collection of built-in steps
The high-level API is what most users of Req will use most of the time.
Examples
Making a GET request with Req.get!/1:
iex> Req.get!("https://api.github.com/repos/wojtekmach/req").body["description"]
"Req is a batteries-included HTTP client for Elixir."Same, but by explicitly building request struct first:
iex> req = Req.new(base_url: "https://api.github.com")
iex> Req.get!(req, url: "/repos/wojtekmach/req").body["description"]
"Req is a batteries-included HTTP client for Elixir."Making a POST request with Req.post!/2:
iex> Req.post!("https://httpbin.org/post", form: [comments: "hello!"]).body["form"]
%{"comments" => "hello!"}Stream request body:
iex> stream = Stream.duplicate("foo", 3)
iex> Req.post!("https://httpbin.org/post", body: stream).body["data"]
"foofoofoo"Stream response body using a callback:
iex> resp =
...> Req.get!("http://httpbin.org/stream/2", into: fn {:data, data}, {req, resp} ->
...> IO.puts(data)
...> {:cont, {req, resp}}
...> end)
# output: {"url": "http://httpbin.org/stream/2", ...}
# output: {"url": "http://httpbin.org/stream/2", ...}
iex> resp.status
200
iex> resp.body
""Stream response body into a Collectable:
iex> resp = Req.get!("http://httpbin.org/stream/2", into: IO.stream())
# output: {"url": "http://httpbin.org/stream/2", ...}
# output: {"url": "http://httpbin.org/stream/2", ...}
iex> resp.status
200
iex> resp.body
%IO.Stream{}Stream response body to the current process:
iex> resp = Req.get!("http://httpbin.org/stream/2", into: :self)
iex> Req.parse_message(resp, receive do message -> message end)
{:ok, [data: "{\"url\": \"http://httpbin.org/stream/2\", ..., \"id\": 0}\n"]}
iex> Req.parse_message(resp, receive do message -> message end)
{:ok, [data: "{\"url\": \"http://httpbin.org/stream/2\", ..., \"id\": 1}\n"]}
iex> Req.parse_message(resp, receive do message -> message end)
{:ok, [:done]}
""Header Names
The HTTP specification requires that header names should be case-insensitive. Req allows two ways to access the headers; using functions and by accessing the data directly:
iex> Req.Response.get_header(response, "content-type")
["text/html"]
iex> response.headers["content-type"]
["text/html"]While we can ensure case-insensitive handling in the former case, we can't in the latter. For this reason, Req made the following design choices:
header names are stored as downcased
functions like
Req.Request.get_header/2,Req.Request.put_header/3,Req.Response.get_header/2,Req.Response.put_header/3, etc automatically downcase the given header name.
Summary
Making Requests
Makes a DELETE request and returns a response or an error.
Makes a DELETE request and returns a response or raises an error.
Makes a GET request and returns a response or an error.
Makes a GET request and returns a response or raises an error.
Makes a HEAD request and returns a response or an error.
Makes a HEAD request and returns a response or raises an error.
Makes a PATCH request and returns a response or an error.
Makes a PATCH request and returns a response or raises an error.
Makes a POST request and returns a response or an error.
Makes a POST request and returns a response or raises an error.
Makes a PUT request and returns a response or an error.
Makes a PUT request and returns a response or raises an error.
Makes an HTTP request and returns a response or an error.
Makes an HTTP request and returns a response or raises an error.
Functions
Cancels an asynchronous response.
Returns default options.
Sets default options for Req.new/1.
Updates a request struct.
Returns a new request struct with built-in steps.
Parses asynchronous response body message.
Making Requests
@spec delete(url() | keyword() | Req.Request.t(), options :: keyword()) :: {:ok, Req.Response.t()} | {:error, Exception.t()}
Makes a DELETE request and returns a response or an error.
request can be one of:
- a
StringorURI; - a
Keywordoptions; - a
Req.Requeststruct
See new/1 for a list of available options.
Examples
With URL:
iex> {:ok, resp} = Req.delete("https://httpbin.org/anything")
iex> resp.body["method"]
"DELETE"With options:
iex> {:ok, resp} = Req.delete(url: "https://httpbin.org/anything")
iex> resp.body["method"]
"DELETE"With request struct:
iex> req = Req.new(url: "https://httpbin.org/anything")
iex> {:ok, resp} = Req.delete(req)
iex> resp.body["method"]
"DELETE"
@spec delete!(url() | keyword() | Req.Request.t(), options :: keyword()) :: Req.Response.t()
Makes a DELETE request and returns a response or raises an error.
request can be one of:
- a
StringorURI; - a
Keywordoptions; - a
Req.Requeststruct
See new/1 for a list of available options.
Examples
With URL:
iex> Req.delete!("https://httpbin.org/anything").body["method"]
"DELETE"With options:
iex> Req.delete!(url: "https://httpbin.org/anything").body["method"]
"DELETE"With request struct:
iex> req = Req.new(url: "https://httpbin.org/anything")
iex> Req.delete!(req).body["method"]
"DELETE"
@spec get(url() | keyword() | Req.Request.t(), options :: keyword()) :: {:ok, Req.Response.t()} | {:error, Exception.t()}
Makes a GET request and returns a response or an error.
request can be one of:
- a
StringorURI; - a
Keywordoptions; - a
Req.Requeststruct
See new/1 for a list of available options.
Examples
With URL:
iex> {:ok, resp} = Req.get("https://api.github.com/repos/wojtekmach/req")
iex> resp.body["description"]
"Req is a batteries-included HTTP client for Elixir."With options:
iex> {:ok, resp} = Req.get(url: "https://api.github.com/repos/wojtekmach/req")
iex> resp.status
200With request struct:
iex> req = Req.new(base_url: "https://api.github.com")
iex> {:ok, resp} = Req.get(req, url: "/repos/elixir-lang/elixir")
iex> resp.status
200
@spec get!(url() | keyword() | Req.Request.t(), options :: keyword()) :: Req.Response.t()
Makes a GET request and returns a response or raises an error.
request can be one of:
- a
StringorURI; - a
Keywordoptions; - a
Req.Requeststruct
See new/1 for a list of available options.
Examples
With URL:
iex> Req.get!("https://api.github.com/repos/wojtekmach/req").body["description"]
"Req is a batteries-included HTTP client for Elixir."With options:
iex> Req.get!(url: "https://api.github.com/repos/wojtekmach/req").status
200With request struct:
iex> req = Req.new(base_url: "https://api.github.com")
iex> Req.get!(req, url: "/repos/elixir-lang/elixir").status
200
@spec head(url() | keyword() | Req.Request.t(), options :: keyword()) :: {:ok, Req.Response.t()} | {:error, Exception.t()}
Makes a HEAD request and returns a response or an error.
request can be one of:
- a
StringorURI; - a
Keywordoptions; - a
Req.Requeststruct
See new/1 for a list of available options.
Examples
With URL:
iex> {:ok, resp} = Req.head("https://httpbin.org/status/201")
iex> resp.status
201With options:
iex> {:ok, resp} = Req.head(url: "https://httpbin.org/status/201")
iex> resp.status
201With request struct:
iex> req = Req.new(base_url: "https://httpbin.org")
iex> {:ok, resp} = Req.head(req, url: "/status/201")
iex> resp.status
201
@spec head!(url() | keyword() | Req.Request.t(), options :: keyword()) :: Req.Response.t()
Makes a HEAD request and returns a response or raises an error.
request can be one of:
- a
StringorURI; - a
Keywordoptions; - a
Req.Requeststruct
See new/1 for a list of available options.
Examples
With URL:
iex> Req.head!("https://httpbin.org/status/201").status
201With options:
iex> Req.head!(url: "https://httpbin.org/status/201").status
201With request struct:
iex> req = Req.new(base_url: "https://httpbin.org")
iex> Req.head!(req, url: "/status/201").status
201
@spec patch(url() | keyword() | Req.Request.t(), options :: keyword()) :: {:ok, Req.Response.t()} | {:error, Exception.t()}
Makes a PATCH request and returns a response or an error.
request can be one of:
- a
StringorURI; - a
Keywordoptions; - a
Req.Requeststruct
See new/1 for a list of available options.
Examples
With URL:
iex> {:ok, resp} = Req.patch("https://httpbin.org/anything", body: "hello!")
iex> resp.body["data"]
"hello!"With options:
iex> {:ok, resp} = Req.patch(url: "https://httpbin.org/anything", body: "hello!")
iex> resp.body["data"]
"hello!"With request struct:
iex> req = Req.new(url: "https://httpbin.org/anything")
iex> {:ok, resp} = Req.patch(req, body: "hello!")
iex> resp.body["data"]
"hello!"
@spec patch!(url() | keyword() | Req.Request.t(), options :: keyword()) :: Req.Response.t()
Makes a PATCH request and returns a response or raises an error.
request can be one of:
- a
StringorURI; - a
Keywordoptions; - a
Req.Requeststruct
See new/1 for a list of available options.
Examples
With URL:
iex> Req.patch!("https://httpbin.org/anything", body: "hello!").body["data"]
"hello!"With options:
iex> Req.patch!(url: "https://httpbin.org/anything", body: "hello!").body["data"]
"hello!"With request struct:
iex> req = Req.new(url: "https://httpbin.org/anything")
iex> Req.patch!(req, body: "hello!").body["data"]
"hello!"
@spec post(url() | keyword() | Req.Request.t(), options :: keyword()) :: {:ok, Req.Response.t()} | {:error, Exception.t()}
Makes a POST request and returns a response or an error.
request can be one of:
- a
StringorURI; - a
Keywordoptions; - a
Req.Requeststruct
See new/1 for a list of available options.
Examples
With URL:
iex> {:ok, resp} = Req.post("https://httpbin.org/anything", body: "hello!")
iex> resp.body["data"]
"hello!"
iex> {:ok, resp} = Req.post("https://httpbin.org/anything", form: [x: 1])
iex> resp.body["form"]
%{"x" => "1"}
iex> {:ok, resp} = Req.post("https://httpbin.org/anything", json: %{x: 2})
iex> resp.body["json"]
%{"x" => 2}With options:
iex> {:ok, resp} = Req.post(url: "https://httpbin.org/anything", body: "hello!")
iex> resp.body["data"]
"hello!"With request struct:
iex> req = Req.new(url: "https://httpbin.org/anything")
iex> {:ok, resp} = Req.post(req, body: "hello!")
iex> resp.body["data"]
"hello!"
@spec post!(url() | keyword() | Req.Request.t(), options :: keyword()) :: Req.Response.t()
Makes a POST request and returns a response or raises an error.
request can be one of:
- a
StringorURI; - a
Keywordoptions; - a
Req.Requeststruct
See new/1 for a list of available options.
Examples
With URL:
iex> Req.post!("https://httpbin.org/anything", body: "hello!").body["data"]
"hello!"
iex> Req.post!("https://httpbin.org/anything", form: [x: 1]).body["form"]
%{"x" => "1"}
iex> Req.post!("https://httpbin.org/anything", json: %{x: 2}).body["json"]
%{"x" => 2}With options:
iex> Req.post!(url: "https://httpbin.org/anything", body: "hello!").body["data"]
"hello!"With request struct:
iex> req = Req.new(url: "https://httpbin.org/anything")
iex> Req.post!(req, body: "hello!").body["data"]
"hello!"
@spec put(url() | keyword() | Req.Request.t(), options :: keyword()) :: {:ok, Req.Response.t()} | {:error, Exception.t()}
Makes a PUT request and returns a response or an error.
request can be one of:
- a
StringorURI; - a
Keywordoptions; - a
Req.Requeststruct
See new/1 for a list of available options.
Examples
With URL:
iex> {:ok, resp} = Req.put("https://httpbin.org/anything", body: "hello!")
iex> resp.body["data"]
"hello!"With options:
iex> {:ok, resp} = Req.put(url: "https://httpbin.org/anything", body: "hello!")
iex> resp.body["data"]
"hello!"With request struct:
iex> req = Req.new(url: "https://httpbin.org/anything")
iex> {:ok, resp} = Req.put(req, body: "hello!")
iex> resp.body["data"]
"hello!"
@spec put!(url() | keyword() | Req.Request.t(), options :: keyword()) :: Req.Response.t()
Makes a PUT request and returns a response or raises an error.
request can be one of:
- a
StringorURI; - a
Keywordoptions; - a
Req.Requeststruct
See new/1 for a list of available options.
Examples
With URL:
iex> Req.put!("https://httpbin.org/anything", body: "hello!").body["data"]
"hello!"With options:
iex> Req.put!(url: "https://httpbin.org/anything", body: "hello!").body["data"]
"hello!"With request struct:
iex> req = Req.new(url: "https://httpbin.org/anything")
iex> Req.put!(req, body: "hello!").body["data"]
"hello!"
@spec request(request :: Req.Request.t() | keyword(), options :: keyword()) :: {:ok, Req.Response.t()} | {:error, Exception.t()}
Makes an HTTP request and returns a response or an error.
request can be one of:
- a
Keywordoptions; - a
Req.Requeststruct
See new/1 for a list of available options.
Examples
With options keywords list:
iex> {:ok, response} = Req.request(url: "https://api.github.com/repos/wojtekmach/req")
iex> response.status
200
iex> response.body["description"]
"Req is a batteries-included HTTP client for Elixir."With request struct:
iex> req = Req.new(url: "https://api.github.com/repos/elixir-lang/elixir")
iex> {:ok, response} = Req.request(req)
iex> response.status
200
@spec request!(request :: Req.Request.t() | keyword(), options :: keyword()) :: Req.Response.t()
Makes an HTTP request and returns a response or raises an error.
See new/1 for a list of available options.
Examples
With options keywords list:
iex> Req.request!(url: "https://api.github.com/repos/elixir-lang/elixir").status
200With request struct:
iex> req = Req.new(url: "https://api.github.com/repos/elixir-lang/elixir")
iex> Req.request!(req).status
200
Types
Functions
Cancels an asynchronous response.
Examples
iex> resp = Req.get!("http://httpbin.org/stream/2", into: self())
iex> Req.cancel_async_response(resp)
:ok
@spec default_options() :: keyword()
Returns default options.
See default_options/1 for more information.
@spec default_options(keyword()) :: :ok
Sets default options for Req.new/1.
Avoid setting default options in libraries as they are global.
Examples
iex> Req.default_options(base_url: "https://httpbin.org")
iex> Req.get!("/statuses/201").status
201
iex> Req.new() |> Req.get!(url: "/statuses/201").status
201
@spec merge(Req.Request.t(), options :: keyword()) :: Req.Request.t()
Updates a request struct.
See new/1 for a list of available options. Also see Req.Request module documentation
for more information on the underlying request struct.
Examples
iex> req = Req.new(base_url: "https://httpbin.org")
iex> req = Req.merge(req, auth: {:basic, "alice:secret"})
iex> req.options[:base_url]
"https://httpbin.org"
iex> req.options[:auth]
{:basic, "alice:secret"}Passing :headers will automatically encode and merge them:
iex> req = Req.new(headers: %{point_x: 1})
iex> req = Req.merge(req, headers: %{point_y: 2})
iex> req.headers
%{"point-x" => ["1"], "point-y" => ["2"]}The same header names are overwritten however:
iex> req = Req.new(headers: %{authorization: "bearer foo"})
iex> req = Req.merge(req, headers: %{authorization: "bearer bar"})
iex> req.headers
%{"authorization" => ["bearer bar"]}Similarly to headers, :params are merged too:
req = Req.new(url: "https://httpbin.org/anything", params: [a: 1, b: 1])
req = Req.merge(req, params: [a: 2])
Req.get!(req).body["args"]
#=> %{"a" => "2", "b" => "1"}
@spec new(options :: keyword()) :: Req.Request.t()
Returns a new request struct with built-in steps.
See Req.Request module documentation for more information on the underlying request struct.
Options
Basic request options:
:method- the request method, defaults to:get.:url- the request URL.:headers- the request headers as a{key, value}enumerable (e.g. map, keyword list).The header names should be downcased.
The headers are automatically encoded using these rules:
atom header names are turned into strings, replacing
_with-. For example,:user_agentbecomes"user-agent".string header names are downcased.
%DateTime{}header values are encoded as "HTTP date".other header values are encoded with
String.Chars.to_string/1.
If you set
:headersoptions both inReq.new/1andrequest/2, the header lists are merged.See also "Header Names" section in the module documentation.
:body- the request body.Can be one of:
iodata- send request body eagerlyenumerable- streamenumerableas request body
Additional URL options:
:base_url- if set, the request URL is prepended with this base URL (viaput_base_urlstep.):params- if set, appends parameters to the request query string (viaput_paramsstep.):path_params- if set, uses a templated request path (viaput_path_paramsstep.)
Authentication options:
:auth- sets request authentication (viaauthstep.)Can be one of:
{:basic, userinfo}- uses Basic HTTP authentication.{:bearer, token}- uses Bearer HTTP authentication.:netrc- load credentials from the default .netrc file.{:netrc, path}- load credentials frompath.string- sets to this value.
:redact_auth- if set totrue, whenReq.Requeststruct is inspected, authentication credentials are redacted. Defaults totrue.
Request body options:
:form- if set, encodes the request body as form data (encode_bodystep.):json- if set, encodes the request body as JSON (encode_bodystep.):compress_body- if set totrue, compresses the request body using gzip (viacompress_bodystep.) Defaults tofalse.
AWS Signature Version 4 options (put_aws_sigv4 step):
: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.:service- the AWS service.:region- if set, AWS region. Defaults to"us-east-1".
This functionality requires :aws_signature dependency:
{:aws_signature, "~> 0.3.0"}Response body options:
:compressed- if set totrue, asks the server to return compressed response. (viacompressedstep.) Defaults totrue.:raw- if set totrue, disables automatic body decompression (decompress_bodystep) and decoding (decode_bodystep.) Defaults tofalse.:decode_body- if set tofalse, disables automatic response body decoding. Defaults totrue.:decode_json- options to pass toJason.decode!/2, defaults to[].:into- where to send the response body. It can be one of:nil- (default) read the whole response body and store it in theresponse.bodyfield.fun- stream response body using a function. The first argument is a{:data, data}tuple containing the chunk of the response body. The second argument is a{request, response}tuple. To continue streaming chunks, return{:cont, {req, resp}}. To cancel, return{:halt, {req, resp}}. For example:into: fn {:data, data}, {req, resp} -> IO.puts(data) {:cont, {req, resp}} endcollectable- stream response body into aCollectable.t/0.:self- stream response body into the process mailbox. The messages should be parsed usingReq.parse_message/2.
Response redirect options (redirect step):
:redirect- if set tofalse, disables automatic response redirects. Defaults totrue.:redirect_trusted- by default, authorization credentials are only sent on redirects with the same host, scheme and port. If:redirect_trustedis set totrue, credentials will be sent to any host.:max_redirects- the maximum number of redirects, defaults to10.
Retry options (retry step):
:retry- can be one of the following::safe_transient(default) - retry safe (GET/HEAD) requests on HTTP 408/429/500/502/503/504 responses or exceptions withreasonfield set to:timeout/:econnrefused/:closed.:transient- same as:safe_transientexcept retries all HTTP methods (POST, DELETE, etc.)fun- a 2-arity function that accepts aReq.Requestand either aReq.Responseor an exception struct and returns one of the following:true- retry with the default delay controller by default delay option described below.{:delay, milliseconds}- retry with the given delay.false/nil- don't retry.
false- don't retry.
:retry_delay- if not set, which is the default, the retry delay is determined by the value ofretry-delayheader on HTTP 429/503 responses. If the header is not set, the default delay follows a simple exponential backoff: 1s, 2s, 4s, 8s, ...:retry_delaycan be set to a function that receives the retry count (starting at 0) and returns the delay, the number of milliseconds to sleep before making another attempt.:retry_log_level- the log level to emit retry logs at. Can also be set tofalseto disable logging these messages. Defaults to:error.:max_retries- maximum number of retry attempts, defaults to3(for a total of4requests to the server, including the initial one.)
Caching options (cache step):
:cache- iftrue, performs HTTP caching. Defaults tofalse.:cache_dir- the directory to store the cache, defaults to<user_cache_dir>/req(see::filename.basedir/3)
Request adapters:
:adapter- adapter to use to make the actual HTTP request. See:adapterfield description in theReq.Requestmodule documentation for more information. Defaults to callingrun_finch.:plug- if set, calls the given Plug instead of making an HTTP request over the network (viaput_plugstep).
Finch options (run_finch step)
:finch- the Finch pool to use. Defaults to pool automatically started byReq.:connect_options- dynamically starts (or re-uses already started) Finch pool with the given connection options::timeout- socket connect timeout in milliseconds, defaults to30_000.:protocols- the HTTP protocols to use, defaults to[:http1].:hostname- Mint explicit hostname.:transport_opts- Mint transport options.:proxy_headers- Mint proxy headers.:proxy- Mint HTTP/1 proxy settings, a{schema, address, port, options}tuple.:client_settings- Mint HTTP/2 client settings.
:inet6- if set to true, uses IPv6. Defaults tofalse.:pool_timeout- pool checkout timeout in milliseconds, defaults to5000.:receive_timeout- socket receive timeout in milliseconds, defaults to15_000.:unix_socket- if set, connect through the given UNIX domain socket.:finch_private- a map or keyword list of private metadata to add to the Finch request. May be useful for adding custom data when handling telemetry withFinch.Telemetry.:finch_request- a function that executes the Finch request, defaults to usingFinch.request/3.
Examples
iex> req = Req.new(url: "https://elixir-lang.org")
iex> req.method
:get
iex> URI.to_string(req.url)
"https://elixir-lang.org"Fake adapter:
iex> fake = fn request ->
...> {request, Req.Response.new(status: 200, body: "it works!")}
...> end
iex>
iex> req = Req.new(adapter: fake)
iex> Req.get!(req).body
"it works!"
Parses asynchronous response body message.
Examples
iex> resp = Req.get!("http://httpbin.org/stream/2", into: self())
iex> Req.parse_message(resp, receive do message -> message end)
{:ok, [data: "{"url": "http://httpbin.org/stream/2", ..., "id": 0}"]}
iex> Req.parse_message(resp, receive do message -> message end)
{:ok, [data: "{"url": "http://httpbin.org/stream/2", ..., "id": 1}"]}
iex> Req.parse_message(resp, receive do message -> message end)
{:ok, [:done]}