Hey everyone, some Req updates since v0.4.0 below.
New step: checksum
Sets expected response body checksum.
iex> resp = Req.get!("https://httpbin.org/json", checksum: "sha1:9274ffd9cf273d4a008750f44540c4c5d4c8227c")
iex> resp.status
200
iex> Req.get!("https://httpbin.org/json", checksum: "sha1:bad")
** (Req.ChecksumMismatchError) checksum mismatch
expected: sha1:bad
actual: sha1:9274ffd9cf273d4a008750f44540c4c5d4c8227c
New step put_aws_sigv4
Signs request with AWS Signature Version 4.
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"),
...> service: :s3
...> ]
...> )
iex>
iex> %{status: 200} = Req.put!(req, "/bucket1/key1", body: "Hello, World!")
iex> resp = Req.get!(req, "/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: "/key1", headers: [content_length: size], body: stream)
iex> byte_size(Req.get!(req, "/bucket1/key1").body)
100_000
Req.Test
Functions for creating test stubs.
Stubs provide canned answers to calls made during the test, usually not responding at all to
anything outside what’s programmed in for the test.
Req has built-in support for stubs via :plug
, :adapter
, and (indirectly) :base_url
options. This module enhances these capabilities by providing:
-
Stub any value with
Req.Test.stub(name, value)
and access it with
Req.Test.stub(name)
. These functions can be used in concurrent tests. -
Access plug stubs with
plug: {Req.Test, name}
. -
Easily create JSON responses for Plug stubs with
Req.Test.json(conn, body)
.
Example
Imagine we’re building an app that displays weather for a given location using an HTTP weather
service:
defmodule MyApp.Weather do
def get_rating(location) do
case get_temperature(location) do
{:ok, %{status: 200, body: %{"celsius" => celsius}}} ->
cond do
celsius < 18.0 -> {:ok, :too_cold}
celsius < 30.0 -> {:ok, :nice}
true -> {:ok, :too_hot}
end
_ ->
:error
end
end
def get_temperature(location) do
[
base_url: "https://weather-service"
]
|> Keyword.merge(Application.get_env(:myapp, :weather_req_options, []))
|> Req.request(options)
end
end
We configure it for production:
# config/runtime.exs
config :myapp, weather_req_options: [
auth: {:bearer, System.fetch_env!("MYAPP_WEATHER_API_KEY")}
]
And tests:
# config/test.exs
config :myapp, weather_req_options: [
plug: {Req.Test, MyApp.Weather}
]
And now we can easily stub out values in concurrent tests:
use ExUnit.Case, async: true
test "nice weather" do
Req.Test.stub(MyApp.Weather, fn conn ->
Req.Test.json(conn, %{"celsius" => 25.0})
end)
assert MyApp.Weather.get_rating("Krakow, Poland") == {:ok, :nice}
end
Full changelog below:
v0.4.10 (2024-02-19)
-
run_finch
: Default toconnect_options: [protocols: [:http1, :http2]]
. -
run_finch
: Change version requirement to~> 0.17
, that is all versions up to1.0
. -
put_aws_sigv4
: Support streaming request body. -
auth
: Always updateauthorization
header. -
decode_body
: Gracefully handle multiple content-type values. -
Req.Request.new/1
: UseURI.parse
for now.
v0.4.9 (2024-02-14)
-
retry
: Raise on invalid return from:retry_delay
function -
run_finch
: Update to Finch 0.17 -
run_finch
: Deprecateconnect_options: [protocol: ...]
in favour of
connect_options: [protocols: ...]]
which defaults to[:http1, :http2]
, that is,
make request using HTTP/1 but if negotiated switch to HTTP/2 over the HTTP/1 connection. -
New step:
put_aws_sigv4
- signs request with AWS Signature Version 4.
v0.4.8 (2023-12-11)
put_plug
: Fix response streaming. Previously we were relying on unreleased
Plug features (which may never get released). Now, Plug adapter will emit the
entire response body as one chunk. Thus,
plug: plug, into: fn ... -> {:halt, acc} end
is not yet supported as it
requires Plug changes that are still being discussed. On the flip side,
we should have much more stable Plug integration regardless of this small
limitation.
v0.4.7 (2023-12-11)
put_plug
: Don’t crash if plug is not installed and :plug is not used
v0.4.6 (2023-12-11)
- New step:
checksum
put_plug
: Fix response streaming when plug usessend_resp
orsend_file
retry
: Retry on:closed
v0.4.5 (2023-10-27)
-
decompress_body
: Removecontent-length
header -
auth
: Deprecateauth: {user, pass}
in favour ofauth: {:basic, "user:pass"}
-
Req.Request
: Allow steps to be{mod, fun, args}
v0.4.4 (2023-10-05)
-
compressed
: Check for optional depenedencies brotli and ezstd only at compile-time.
(backported from v0.3.12.) -
decode_body
: Check for optional depenedency nimble_csv at compile-time.
(backported from v0.3.12.) -
run_finch
: Add:finch_private
option
v0.4.3 (2023-09-13)
-
Req.new/1
: Fix setting:redact_auth
-
Req.Request
: AddReq.Request.get_option_lazy/3
-
Req.Request
: AddReq.Request.drop_options/2
v0.4.2 (2023-09-04)
-
put_plug
: Handle response streaming on Plug 1.15+. -
Don’t warn on mixed-case header names
v0.4.1 (2023-09-01)
- Fix Req.Request Inspect regression