### Quick start with Mix.install and Req.get! Source: https://req.hexdocs.pm/ Install Req and fetch a GitHub repository description. The example uses Mix.install to add the dependency and Req.get! to make a request, then accesses the 'description' field from the decoded JSON body. ```elixir Mix.install([ {:req, "~> 0.5.0"} ]) Req.get!("https://api.github.com/repos/wojtekmach/req").body["description"] #=> "Req is a batteries-included HTTP client for Elixir." ``` -------------------------------- ### new example: from keyword list Source: https://req.hexdocs.pm/Req.Response.md Example showing how to create a new response from a keyword list. ```elixir iex> Req.Response.new(status: 200, body: "body") %Req.Response{status: 200, headers: %{}, body: "body"} ``` -------------------------------- ### run_request/1 example Source: https://req.hexdocs.pm/Req.Request.md Doctest example showing how to run a request and inspect the response status and host. ```elixir iex> req = Req.Request.new(url: "https://api.github.com/repos/wojtekmach/req") iex> {request, response} = Req.Request.run_request(req) iex> request.url.host "api.github.com" iex> response.status 200 ``` -------------------------------- ### prepend_response_steps example Source: https://req.hexdocs.pm/Req.Request.md Example usage of prepend_response_steps, adding a noop step and an inspect step. ```elixir Req.Request.prepend_response_steps(request, noop: fn {request, response} -> {request, response} end, inspect: &IO.inspect/1 ) ``` -------------------------------- ### verify_on_exit! as ExUnit callback Source: https://req.hexdocs.pm/Req.Test.md Example of using verify_on_exit! as an ExUnit callback in a setup block. ```elixir setup {Req.Test, :verify_on_exit!} ``` -------------------------------- ### new example: from Finch.Response struct Source: https://req.hexdocs.pm/Req.Response.md Example showing how to create a new response from a Finch.Response struct. ```elixir iex> finch_response = %Finch.Response{status: 200, headers: [{"content-type", "text/html"}]} iex> Req.Response.new(finch_response) %Req.Response{status: 200, headers: %{"content-type" => ["text/html"]}, body: ""} ``` -------------------------------- ### append_response_steps/2 example Source: https://req.hexdocs.pm/Req.Request.md Example showing how to append response steps to a request. The example adds a noop step and an inspect step using IO.inspect/1. ```elixir Req.Request.append_response_steps(request, noop: fn {request, response} -> {request, response} end, inspect: &IO.inspect/1 ) ``` -------------------------------- ### Req.head/2 examples with URL, options, and request struct Source: https://req.hexdocs.pm/Req.md Three interactive examples showing how to call Req.head/2 with a URL, options keyword list, or a request struct. The third example creates a request with Req.new/1 and passes a relative URL. ```elixir iex> {:ok, resp} = Req.head("https://httpbin.org/status/201") iex> resp.status 201 ``` ```elixir iex> {:ok, resp} = Req.head(url: "https://httpbin.org/status/201") iex> resp.status 201 ``` ```elixir iex> req = Req.new(base_url: "https://httpbin.org") iex> {:ok, resp} = Req.head(req, url: "/status/201") iex> resp.status 201 ``` -------------------------------- ### prepend_request_steps example Source: https://req.hexdocs.pm/Req.Request.md Example usage of prepend_request_steps, adding a noop step and an inspect step. ```elixir Req.Request.prepend_request_steps(request, noop: fn request -> request end, inspect: &IO.inspect/1 ) ``` -------------------------------- ### Req.head!/2 examples with URL, options, and request struct Source: https://req.hexdocs.pm/Req.md Three interactive examples showing how to call Req.head!/2 with a URL, options keyword list, or a request struct. The third example creates a request with Req.new/1 and uses a relative URL. ```elixir iex> Req.head!("https://httpbin.org/status/201").status 201 ``` ```elixir iex> Req.head!(url: "https://httpbin.org/status/201").status 201 ``` ```elixir iex> req = Req.new(base_url: "https://httpbin.org") iex> Req.head!(req, url: "/status/201").status 201 ``` -------------------------------- ### append_request_steps/2 example Source: https://req.hexdocs.pm/Req.Request.md Example showing how to append request steps to a request. The example adds a noop step and an inspect step using IO.inspect/1. ```elixir Req.Request.append_request_steps(request, noop: fn request -> request end, inspect: &IO.inspect/1 ) ``` -------------------------------- ### put_headers/2 example Source: https://req.hexdocs.pm/Req.Request.md Example showing how to add multiple headers using put_headers/2 and then retrieve them with get_header/2. ```elixir iex> req = Req.new() iex> req = Req.Request.put_headers(req, [{"accept", "text/html"}, {"accept-encoding", "gzip"}]) iex> Req.Request.get_header(req, "accept") ["text/html"] iex> Req.Request.get_header(req, "accept-encoding") ["gzip"] ``` -------------------------------- ### put_header example with get_header Source: https://req.hexdocs.pm/Req.Request.md Example showing how to set a header with put_header and verify it with get_header. The header value is overwritten if previously set. ```elixir iex> req = Req.new() iex> Req.Request.get_header(req, "accept") [] iex> req = Req.Request.put_header(req, "accept", "application/json") iex> Req.Request.get_header(req, "accept") ["application/json"] ``` -------------------------------- ### redirect example Source: https://req.hexdocs.pm/Req.Test.md Example showing how to use Req.Test.redirect/2 to redirect requests to a path, with a fallback handler. ```elixir iex> plug = fn ...> conn when conn.request_path == nil -> ...> Req.Test.redirect(conn, to: "/hello") ...> ...> conn when conn.request_path == "/hello" -> ...> Req.Test.text(conn, "Hello, World!") ...> end iex> iex> resp = Req.get!(plug: plug, url: "http://example.com") # 14:53:06.101 [debug] redirecting to /hello iex> resp.body "Hello, World!" ``` -------------------------------- ### get_header example Source: https://req.hexdocs.pm/Req.Response.md Example of retrieving the content-type header from a response, returning a list with the value. ```elixir iex> Req.Response.get_header(response, "content-type") ["application/json"] ``` -------------------------------- ### prepend_error_steps example Source: https://req.hexdocs.pm/Req.Request.md Example usage of prepend_error_steps, adding a noop step and an inspect step. ```elixir Req.Request.prepend_error_steps(request, noop: fn {request, exception} -> {request, exception} end, inspect: &IO.inspect/1 ) ``` -------------------------------- ### Req.request/2 examples with keyword and request struct Source: https://req.hexdocs.pm/Req.md Two examples showing how to call Req.request/2 with a keyword list and with a Req.Request struct. The first also accesses the response body's description field and expects status 200. ```elixir {:ok, response} = Req.request(url: "https://api.github.com/repos/wojtekmach/req") response.status response.body["description"] ``` ```elixir req = Req.new(url: "https://api.github.com/repos/elixir-lang/elixir") {:ok, response} = Req.request(req) response.status ``` -------------------------------- ### Custom connect_options examples Source: https://req.hexdocs.pm/Req.Finch.md Two examples of custom connection options: setting a 5-second socket connect timeout and selecting HTTP/2 protocol. ```elixir iex> Req.get!(url, connect_options: [timeout: 5000]) ``` ```elixir iex> Req.get!(url, connect_options: [protocols: [:http2]]) ``` -------------------------------- ### Req.post! with options Source: https://req.hexdocs.pm/Req.md Example using Req.post!/2 with options keyword list. ```elixir iex> Req.post!(url: "https://httpbin.org/anything", body: "hello!").body["data"] "hello!" ``` -------------------------------- ### put_header example Source: https://req.hexdocs.pm/Req.Response.md Example usage of put_header, showing how to add a content-type header to a response and inspect the resulting headers. ```elixir iex> resp = Req.Response.put_header(%Req.Response{}, "content-type", "application/json") iex> resp.headers %{"content-type" => ["application/json"]} ``` -------------------------------- ### Req.patch/2 examples with URL, options, and request struct Source: https://req.hexdocs.pm/Req.md Three interactive examples showing how to call Req.patch/2 with a URL, options keyword list, or a request struct. The request struct is created with Req.new/1 and then passed to Req.patch/2 with the body option. ```elixir iex> {:ok, resp} = Req.patch("https://httpbin.org/anything", body: "hello!") iex> resp.body["data"] "hello!" ``` ```elixir iex> {:ok, resp} = Req.patch(url: "https://httpbin.org/anything", body: "hello!") iex> resp.body["data"] "hello!" ``` ```elixir iex> req = Req.new(url: "https://httpbin.org/anything") iex> {:ok, resp} = Req.patch(req, body: "hello!") iex> resp.body["data"] "hello!" ``` -------------------------------- ### text example Source: https://req.hexdocs.pm/Req.Test.md Example showing how to use Req.Test.text/2 to send a text response and verify the content type. ```elixir iex> plug = fn conn -> ...> Req.Test.text(conn, "Hello, World!") ...> end iex> iex> resp = Req.get!(plug: plug) iex> resp.headers["content-type"] ["text/plain; charset=utf-8"] iex> resp.body "Hello, World!" ``` -------------------------------- ### expect example with retries Source: https://req.hexdocs.pm/Req.Test.md Example of using Req.Test.expect/3 to simulate a server that fails then succeeds, with retry warnings shown. ```elixir iex> Req.Test.expect(MyStub, &Req.Test.transport_error(&1, :econnrefused)) iex> Req.Test.expect(MyStub, 2, &Plug.Conn.send_resp(&1, 500, "internal server error")) iex> Req.Test.expect(MyStub, &Plug.Conn.send_resp(&1, 200, "ok")) iex> Req.get!(plug: {Req.Test, MyStub}).body # 15:57:06.309 [warning] retry: got exception, will retry in 1000ms, 3 attempts left # 15:57:06.309 [warning] ** (Req.TransportError) connection refused # 15:57:07.310 [warning] retry: got response with status 500, will retry in 2000ms, 2 attempts left # 15:57:09.311 [warning] retry: got response with status 500, will retry in 4000ms, 1 attempt left "ok" ``` -------------------------------- ### raw_body example Source: https://req.hexdocs.pm/Req.Test.md Example showing how to use Req.Test.raw_body/1 to read the raw request body and send it as the response. ```elixir iex> echo = fn conn -> ...> body = Req.Test.raw_body(conn) ...> Plug.Conn.send_resp(conn, 200, body) ...> end iex> iex> resp = Req.post!(plug: echo, json: %{hello: "world"}) iex> resp.body "{\"hello\":\"world\"}" ``` -------------------------------- ### json example: build response with JSON body Source: https://req.hexdocs.pm/Req.Response.md Example showing how to build a response with a JSON body using Req.Response.json/1. ```elixir iex> Req.Response.json(%{hello: 42}) %Req.Response{ status: 200, headers: %{"content-type" => ["application/json"]}, body: ~s|{"hello":42}| } ``` -------------------------------- ### to_map example Source: https://req.hexdocs.pm/Req.Response.md Example usage of to_map, showing conversion of a response with status, headers, and body to a map. ```elixir iex> resp = Req.Response.new(status: 200, headers: %{"server" => ["test"]}, body: "hello") iex> Req.Response.to_map(resp) %{status: 200, body: "hello", headers: [{"server", "test"}], trailers: []} ``` -------------------------------- ### Req.patch!/2 examples (IEEx) Source: https://req.hexdocs.pm/Req.md Examples of Req.patch!/2 with a URL, with options (keyword list), and with a request struct. Each sends a PATCH request to https://httpbin.org/anything with body "hello!" and returns the response body's data field. ```iex iex> Req.patch!("https://httpbin.org/anything", body: "hello!").body["data"] "hello!" ``` ```iex iex> Req.patch!(url: "https://httpbin.org/anything", body: "hello!").body["data"] "hello!" ``` ```iex iex> req = Req.new(url: "https://httpbin.org/anything") iex> Req.patch!(req, body: "hello!").body["data"] "hello!" ``` -------------------------------- ### expect example with missing stub Source: https://req.hexdocs.pm/Req.Test.md Example showing that fetching a name without a defined expectation raises a RuntimeError. ```elixir iex> Req.request!(plug: {Req.Test, MyStub}) ** (RuntimeError) no mock or stub for MyStub ``` -------------------------------- ### Req.put with options Source: https://req.hexdocs.pm/Req.md Example using Req.put/2 with options keyword list. ```elixir iex> {:ok, resp} = Req.put(url: "https://httpbin.org/anything", body: "hello!") iex> resp.body["data"] "hello!" ``` -------------------------------- ### halt spec and example Source: https://req.hexdocs.pm/Req.Request.md Spec for halt/2 and an example showing how to halt the request pipeline from a request step when a circuit breaker is open. ```elixir @spec halt(t(), response_or_exception) :: {t(), response_or_exception} when response_or_exception: Req.Response.t() | Exception.t() ``` ```elixir Req.Request.prepend_request_steps(request, circuit_breaker: fn request -> if CircuitBreaker.open?() do Req.Request.halt(request, RuntimeError.exception("circuit breaker is open")) else request end end) ``` -------------------------------- ### Configure custom decoders with :decoders option Source: https://req.hexdocs.pm/Req.Steps.md Shows how to configure the `:decoders` option. The first example replaces the default decoders with JSON, zip, and tar. The second example uses a custom 1-arity function decoder for the `:ics` format. ```elixir # handles json, zip, and tar: Req.new(decoders: [:json, :zip, :tar]) ``` ```elixir Req.get!(url, decoders: [ics: &{:ok, ICal.from_ics(&1)}]) ``` -------------------------------- ### Req.put!/2 examples with URL, keyword, and request struct Source: https://req.hexdocs.pm/Req.md Three examples showing how to call Req.put!/2 with a URL string, a keyword list of options, and a Req.Request struct. All return the response body's "data" field, which echoes the sent body. ```elixir Req.put!("https://httpbin.org/anything", body: "hello!").body["data"] ``` ```elixir Req.put!(url: "https://httpbin.org/anything", body: "hello!").body["data"] ``` ```elixir req = Req.new(url: "https://httpbin.org/anything") Req.put!(req, body: "hello!").body["data"] ``` -------------------------------- ### get_option spec and examples Source: https://req.hexdocs.pm/Req.Request.md Spec for get_option/3 and examples showing retrieval of an existing option, a missing option returning nil, and a missing option with a default value. ```elixir @spec get_option(t(), atom(), term()) :: term() ``` ```elixir iex> req = Req.Request.new(options: [a: 1]) iex> Req.Request.get_option(req, :a) 1 iex> Req.Request.get_option(req, :b) nil iex> Req.Request.get_option(req, :b, 0) 0 ``` -------------------------------- ### register_options/2 spec and examples Source: https://req.hexdocs.pm/Req.Request.md Specifies register_options/2 and shows examples: error messages for mistyped options and a full workflow registering a custom option and using it. ```elixir @spec register_options(t(), [atom()]) :: t() ``` ```elixir iex> Req.request!(urll: "https://httpbin.org") ** (ArgumentError) unknown option :urll. Did you mean :url? ``` ```elixir iex> Req.new(bas_url: "https://httpbin.org") ** (ArgumentError) unknown option :bas_url. Did you mean :base_url? ``` ```elixir req = Req.new(base_url: "https://httpbin.org") |> Req.Request.register_options([:foo]) Req.get!(req, url: "/status/201", foo: :bar).status #=> 201 ``` -------------------------------- ### stub usage example Source: https://req.hexdocs.pm/Req.Test.md Example showing how to register a stub with Req.Test.stub/2 and then make a request using the plug option. The stub sends a message to the test process and returns an empty JSON body. ```elixir iex> Req.Test.stub(MyStub, fn conn -> ...> send(self(), :req_happened) ...> Req.Test.json(conn, %{}) ...> end) :ok iex> Req.get!(plug: {Req.Test, MyStub}).body %{} iex> receive do ...> :req_happened -> :ok ...> end :ok ``` -------------------------------- ### new example: creates request and runs it Source: https://req.hexdocs.pm/Req.Request.md Shows creating a request with new/1 and running it with run_request/1, then accessing the response status. ```elixir iex> req = Req.Request.new(url: "https://api.github.com/repos/wojtekmach/req") iex> {req, resp} = Req.Request.run_request(req) iex> req.url.host "api.github.com" iex> resp.status 200 ``` -------------------------------- ### compressed: Decompressed and Raw Response Examples Source: https://req.hexdocs.pm/Req.Steps.md Examples of the `compressed` request option. The first shows that with `compressed: true`, the response body is decompressed, so the first 15 bytes are ``. The second shows that adding `raw: true` disables decompression, so the body starts with the gzip magic bytes `<<31, 139>>` and the `content-encoding` header is `gzip`. ```elixir iex> response = Req.get!("https://elixir-lang.org", compressed: true) iex> response.body |> binary_part(0, 15) "" ``` ```elixir iex> response = Req.get!("https://elixir-lang.org", compressed: true, raw: true) iex> Req.Response.get_header(response, "content-encoding") ["gzip"] iex> response.body |> binary_part(0, 2) <<31, 139>> ``` -------------------------------- ### append_error_steps/2 example Source: https://req.hexdocs.pm/Req.Request.md Example showing how to append error steps to a request. The example adds a noop step and an inspect step using IO.inspect/1. ```elixir Req.Request.append_error_steps(request, noop: fn {request, exception} -> {request, exception} end, inspect: &IO.inspect/1 ) ``` -------------------------------- ### auth: Basic, Digest, Bearer, and Netrc Authentication Examples Source: https://req.hexdocs.pm/Req.Steps.md Examples of the `auth` request option in Req, showing basic, digest, bearer, and netrc authentication. The basic examples show that a wrong password returns 401 and a correct one returns 200; the digest example returns 200; the bearer examples show that an empty token returns 401 and a non-empty token returns 200; the netrc examples show that loading credentials from a file (or via a function) returns 200. The `{Authentication, :fetch_token, []}` example assumes a module named `Authentication` with a `fetch_token/0` function. ```elixir iex> Req.get!("https://httpbin.org/basic-auth/foo/bar", auth: {:basic, "foo:foo"}).status 401 iex> Req.get!("https://httpbin.org/basic-auth/foo/bar", auth: {:basic, "foo:bar"}).status 200 iex> Req.get!("https://httpbin.org/basic-auth/foo/bar", auth: fn -> {:basic, "foo:bar"} end).status 200 iex> Req.get!("https://httpbin.org/basic-auth/foo/bar", auth: {Authentication, :fetch_token, []}).status 200 ``` ```elixir iex> Req.get!("https://httpbin.org/digest-auth/auth/user/pass", auth: {:digest, "user:pass"}).status 200 ``` ```elixir iex> Req.get!("https://httpbin.org/bearer", auth: {:bearer, ""}).status 401 iex> Req.get!("https://httpbin.org/bearer", auth: {:bearer, "foo"}).status 200 iex> Req.get!("https://httpbin.org/bearer", auth: fn -> {:bearer, "foo"} end).status 200 ``` ```elixir iex> System.put_env("NETRC", "./test/my_netrc") iex> Req.get!("https://httpbin.org/basic-auth/foo/bar", auth: :netrc).status 200 ``` ```elixir iex> Req.get!("https://httpbin.org/basic-auth/foo/bar", auth: {:netrc, "./test/my_netrc"}).status 200 iex> Req.get!("https://httpbin.org/basic-auth/foo/bar", auth: fn -> {:netrc, "./test/my_netrc"} end).status 200 ``` -------------------------------- ### Use Req plugins with Mix.install and attach Source: https://req.hexdocs.pm/ Shows how to install and attach multiple Req plugins (ReqEasyHTML, ReqS3, ReqHex, ReqGitHubOAuth) to a request struct. Demonstrates various plugin features including HTML parsing, S3 downloads, Hex package metadata, and GitHub OAuth device flow. ```elixir Mix.install([ {:req, "~> 0.5.0"}, {:req_easyhtml, "~> 0.2.0"}, {:req_s3, "~> 0.2.3"}, {:req_hex, "~> 0.2.0"}, {:req_github_oauth, "~> 0.1.0"} ]) req = (Req.new(http_errors: :raise) |> ReqEasyHTML.attach() |> ReqS3.attach() |> ReqHex.attach() |> ReqGitHubOAuth.attach()) Req.get!(req, url: "https://elixir-lang.org").body[".entry-summary h5"] #=> # #EasyHTML[