Skip to content

Commit 56018e3

Browse files
committed
Replace hackney with Req and Jason with built-in JSON
- Migrate HTTP client from hackney to Req - Configure ex_aws to use ExAws.Request.Req (built into ex_aws 2.6.0) - Configure Sentry to use Finch client - Replace Jason with Elixir's built-in JSON module
1 parent 062c777 commit 56018e3

File tree

7 files changed

+73
-52
lines changed

7 files changed

+73
-52
lines changed

config/config.exs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,10 @@ config :hexdocs, :docs_private_bucket, name: "hexdocs-private-staging"
4343
config :hexdocs, :docs_public_bucket, name: "hexdocs-public-staging"
4444

4545
config :ex_aws,
46-
http_client: ExAws.Request.Hackney,
47-
json_codec: Jason
46+
http_client: ExAws.Request.Req,
47+
json_codec: JSON
48+
49+
config :sentry, client: Sentry.FinchClient
4850

4951
config :logger, :console, format: "[$level] $metadata$message\n"
5052

lib/hexdocs/cdn/fastly.ex

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,20 +29,18 @@ defmodule Hexdocs.CDN.Fastly do
2929
url = @fastly_url <> url
3030

3131
headers = [
32-
"fastly-key": auth(),
33-
accept: "application/json",
34-
"content-type": "application/json"
32+
{"fastly-key", auth()},
33+
{"accept", "application/json"},
34+
{"content-type", "application/json"}
3535
]
3636

3737
body = JSON.encode!(body)
3838

39-
Hexdocs.HTTP.retry("fastly", url, fn -> :hackney.post(url, headers, body, []) end)
40-
|> read_body()
39+
Hexdocs.HTTP.retry("fastly", url, fn -> Hexdocs.HTTP.post(url, headers, body) end)
40+
|> decode_body()
4141
end
4242

43-
defp read_body({:ok, status, headers, client}) do
44-
{:ok, body} = :hackney.body(client)
45-
43+
defp decode_body({:ok, status, headers, body}) do
4644
body =
4745
case JSON.decode(body) do
4846
{:ok, map} -> map

lib/hexdocs/http.ex

Lines changed: 51 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,62 +5,84 @@ defmodule Hexdocs.HTTP do
55
require Logger
66

77
def head(url, headers) do
8-
:hackney.head(url, headers)
8+
case Req.head(url, headers: headers, retry: false) do
9+
{:ok, response} ->
10+
{:ok, response.status, response.headers |> Enum.to_list()}
11+
12+
{:error, reason} ->
13+
{:error, reason}
14+
end
915
end
1016

11-
def get(url, headers, opts \\ []) do
12-
:hackney.get(url, headers, "", opts)
13-
|> read_response()
17+
def get(url, headers, _opts \\ []) do
18+
case Req.get(url, headers: headers, retry: false) do
19+
{:ok, response} ->
20+
{:ok, response.status, response.headers |> Enum.to_list(), response.body}
21+
22+
{:error, reason} ->
23+
{:error, reason}
24+
end
1425
end
1526

1627
def get_stream(url, headers) do
17-
:hackney.get(url, headers)
18-
|> stream_response()
28+
case Req.get(url, headers: headers, retry: false, into: :self) do
29+
{:ok, response} ->
30+
stream = stream_body(response.body)
31+
{:ok, response.status, response.headers |> Enum.to_list(), stream}
32+
33+
{:error, reason} ->
34+
{:error, reason}
35+
end
1936
end
2037

2138
def put(url, headers, body) do
22-
:hackney.put(url, headers, body, recv_timeout: 10_000)
23-
|> read_response()
24-
end
39+
case Req.put(url, headers: headers, body: body, retry: false, receive_timeout: 10_000) do
40+
{:ok, response} ->
41+
{:ok, response.status, response.headers |> Enum.to_list(), response.body}
2542

26-
def post(url, headers, body, opts \\ []) do
27-
:hackney.post(url, headers, body, opts)
28-
|> read_response()
43+
{:error, reason} ->
44+
{:error, reason}
45+
end
2946
end
3047

31-
def delete(url, headers, opts \\ []) do
32-
:hackney.delete(url, headers, "", opts)
33-
|> read_response()
48+
def post(url, headers, body, _opts \\ []) do
49+
case Req.post(url, headers: headers, body: body, retry: false) do
50+
{:ok, response} ->
51+
{:ok, response.status, response.headers |> Enum.to_list(), response.body}
52+
53+
{:error, reason} ->
54+
{:error, reason}
55+
end
3456
end
3557

36-
defp read_response(result) do
37-
with {:ok, status, headers, ref} <- result,
38-
{:ok, body} <- :hackney.body(ref) do
39-
{:ok, status, headers, body}
58+
def delete(url, headers, _opts \\ []) do
59+
case Req.delete(url, headers: headers, retry: false) do
60+
{:ok, response} ->
61+
{:ok, response.status, response.headers |> Enum.to_list(), response.body}
62+
63+
{:error, reason} ->
64+
{:error, reason}
4065
end
4166
end
4267

43-
defp stream_response({:ok, status, headers, ref}) do
68+
defp stream_body(ref) do
4469
start_fun = fn -> :cont end
4570
after_fun = fn _ -> :ok end
4671

4772
next_fun = fn
4873
:cont ->
49-
case :hackney.stream_body(ref) do
50-
{:ok, data} -> {[{:ok, data}], :cont}
51-
:done -> {:halt, :ok}
52-
{:error, reason} -> {[{:error, reason}], :stop}
74+
receive do
75+
{^ref, {:data, data}} -> {[{:ok, data}], :cont}
76+
{^ref, :done} -> {:halt, :ok}
77+
after
78+
30_000 -> {[{:error, :timeout}], :stop}
5379
end
5480

5581
:stop ->
5682
{:halt, :ok}
5783
end
5884

59-
{:ok, status, headers, Stream.resource(start_fun, next_fun, after_fun)}
60-
end
61-
62-
defp stream_response(other) do
63-
other
85+
Stream.resource(start_fun, next_fun, after_fun)
6486
end
6587

6688
def retry(service, url, fun) do

lib/hexdocs/oauth.ex

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,17 +112,17 @@ defmodule Hexdocs.OAuth do
112112
"code_verifier" => code_verifier
113113
}
114114
|> maybe_put("name", opts[:name])
115-
|> Jason.encode!()
115+
|> JSON.encode!()
116116

117117
url = "#{hexpm_url}/api/oauth/token"
118118
headers = [{"content-type", "application/json"}]
119119

120120
case Hexdocs.HTTP.post(url, headers, body) do
121121
{:ok, status, _headers, response_body} when status in 200..299 ->
122-
{:ok, Jason.decode!(response_body)}
122+
{:ok, JSON.decode!(response_body)}
123123

124124
{:ok, status, _headers, response_body} ->
125-
{:error, {status, Jason.decode!(response_body)}}
125+
{:error, {status, JSON.decode!(response_body)}}
126126

127127
{:error, reason} ->
128128
{:error, reason}
@@ -151,7 +151,7 @@ defmodule Hexdocs.OAuth do
151151
client_secret = Keyword.fetch!(opts, :client_secret)
152152

153153
body =
154-
Jason.encode!(%{
154+
JSON.encode!(%{
155155
"grant_type" => "refresh_token",
156156
"refresh_token" => refresh_token,
157157
"client_id" => client_id,
@@ -163,10 +163,10 @@ defmodule Hexdocs.OAuth do
163163

164164
case Hexdocs.HTTP.post(url, headers, body) do
165165
{:ok, status, _headers, response_body} when status in 200..299 ->
166-
{:ok, Jason.decode!(response_body)}
166+
{:ok, JSON.decode!(response_body)}
167167

168168
{:ok, status, _headers, response_body} ->
169-
{:error, {status, Jason.decode!(response_body)}}
169+
{:error, {status, JSON.decode!(response_body)}}
170170

171171
{:error, reason} ->
172172
{:error, reason}

mix.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ defmodule Hexdocs.MixProject do
4242
{:ex_aws_s3, "~> 2.0"},
4343
{:ex_aws_sqs, "~> 3.0"},
4444
{:goth, "~> 1.0"},
45-
{:hackney, "~> 1.13"},
45+
{:req, "~> 0.5.0"},
4646
{:logster, "~> 1.0"},
4747
{:plug_cowboy, "~> 2.0"},
4848
{:sentry, "~> 11.0"},

mix.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
"finch": {:hex, :finch, "0.20.0", "5330aefb6b010f424dcbbc4615d914e9e3deae40095e73ab0c1bb0968933cadf", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2658131a74d051aabfcba936093c903b8e89da9a1b63e430bee62045fa9b2ee2"},
1212
"gen_stage": {:hex, :gen_stage, "1.3.2", "7c77e5d1e97de2c6c2f78f306f463bca64bf2f4c3cdd606affc0100b89743b7b", [:mix], [], "hexpm", "0ffae547fa777b3ed889a6b9e1e64566217413d018cabd825f786e843ffe63e7"},
1313
"goth": {:hex, :goth, "1.4.5", "ee37f96e3519bdecd603f20e7f10c758287088b6d77c0147cd5ee68cf224aade", [:mix], [{:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:jose, "~> 1.11", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "0fc2dce5bd710651ed179053d0300ce3a5d36afbdde11e500d57f05f398d5ed5"},
14-
"hackney": {:hex, :hackney, "1.25.0", "390e9b83f31e5b325b9f43b76e1a785cbdb69b5b6cd4e079aa67835ded046867", [:rebar3], [{:certifi, "~> 2.15.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~> 6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~> 1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~> 1.4", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.4.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~> 0.7.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "7209bfd75fd1f42467211ff8f59ea74d6f2a9e81cbcee95a56711ee79fd6b1d4"},
1514
"hex_core": {:hex, :hex_core, "0.11.0", "d1c6bbf2a4ee6b5f002bec6fa52b5080c53c8b63b7caf6eb88b943687547bff4", [:rebar3], [], "hexpm", "707893677a425491962a2db522f1d2b1f85f97ea27418b06f7929f1d30cde0b0"},
1615
"hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"},
1716
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},
@@ -31,6 +30,7 @@
3130
"plug_cowboy": {:hex, :plug_cowboy, "2.7.4", "729c752d17cf364e2b8da5bdb34fb5804f56251e88bb602aff48ae0bd8673d11", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "9b85632bd7012615bae0a5d70084deb1b25d2bcbb32cab82d1e9a1e023168aa3"},
3231
"plug_crypto": {:hex, :plug_crypto, "2.1.1", "19bda8184399cb24afa10be734f84a16ea0a2bc65054e23a62bb10f06bc89491", [:mix], [], "hexpm", "6470bce6ffe41c8bd497612ffde1a7e4af67f36a15eea5f921af71cf3e11247c"},
3332
"ranch": {:hex, :ranch, "2.2.0", "25528f82bc8d7c6152c57666ca99ec716510fe0925cb188172f41ce93117b1b0", [:make, :rebar3], [], "hexpm", "fa0b99a1780c80218a4197a59ea8d3bdae32fbff7e88527d7d8a4787eff4f8e7"},
33+
"req": {:hex, :req, "0.5.17", "0096ddd5b0ed6f576a03dde4b158a0c727215b15d2795e59e0916c6971066ede", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "0b8bc6ffdfebbc07968e59d3ff96d52f2202d0536f10fef4dc11dc02a2a43e39"},
3434
"saxy": {:hex, :saxy, "1.6.0", "02cb4e9bd045f25ac0c70fae8164754878327ee393c338a090288210b02317ee", [:mix], [], "hexpm", "ef42eb4ac983ca77d650fbdb68368b26570f6cc5895f0faa04d34a6f384abad3"},
3535
"sentry": {:hex, :sentry, "11.0.4", "60371c96cefd247e0fc98840bba2648f64f19aa0b8db8e938f5a98421f55b619", [:mix], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: true]}, {:igniter, "~> 0.5", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: true]}, {:nimble_options, "~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_ownership, "~> 0.3.0 or ~> 1.0", [hex: :nimble_ownership, repo: "hexpm", optional: false]}, {:opentelemetry, ">= 0.0.0", [hex: :opentelemetry, repo: "hexpm", optional: true]}, {:opentelemetry_api, ">= 0.0.0", [hex: :opentelemetry_api, repo: "hexpm", optional: true]}, {:opentelemetry_exporter, ">= 0.0.0", [hex: :opentelemetry_exporter, repo: "hexpm", optional: true]}, {:opentelemetry_semantic_conventions, ">= 0.0.0", [hex: :opentelemetry_semantic_conventions, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6", [hex: :phoenix, repo: "hexpm", optional: true]}, {:phoenix_live_view, "~> 0.20 or ~> 1.0", [hex: :phoenix_live_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.6", [hex: :plug, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "feaafc284dc204c82aadaddc884227aeaa3480decb274d30e184b9d41a700c66"},
3636
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"},

test/hexdocs/search_test.exs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -337,10 +337,10 @@ defmodule Hexdocs.SearchTest do
337337
headers = [{"x-typesense-api-key", api_key}, {"content-type", "application/json"}]
338338
payload = JSON.encode_to_iodata!(Typesense.collection_schema(collection))
339339

340-
assert {:ok, 201, _resp_headers, _ref} =
341-
:hackney.post("http://localhost:8108/collections", headers, payload)
340+
assert {:ok, 201, _resp_headers, _body} =
341+
Hexdocs.HTTP.post("http://localhost:8108/collections", headers, payload)
342342

343-
on_exit(fn -> :hackney.delete("http://localhost:8108/collections/#{collection}", headers) end)
343+
on_exit(fn -> Hexdocs.HTTP.delete("http://localhost:8108/collections/#{collection}", headers) end)
344344
end
345345

346346
defp typesense_search(query) do
@@ -352,8 +352,7 @@ defmodule Hexdocs.SearchTest do
352352
URI.encode_query(query)
353353

354354
headers = [{"x-typesense-api-key", api_key}]
355-
assert {:ok, 200, _resp_headers, ref} = :hackney.get(url, headers)
356-
assert {:ok, body} = :hackney.body(ref)
355+
assert {:ok, 200, _resp_headers, body} = Hexdocs.HTTP.get(url, headers)
357356
assert %{"hits" => hits} = JSON.decode!(body)
358357
hits
359358
end

0 commit comments

Comments
 (0)