Current section

Files

Jump to
req_client lib req_client.ex
Raw

lib/req_client.ex

defmodule ReqClient do
@moduledoc """
Request Client based on Req & Finch & Mint!
No client-level process now, all use Req, just a smiple wraper!
iex> ReqClient.get!("https://slink.fly.dev/api/ping")
iex> ReqClient.get!("https://api.github.com/repos/elixir-lang/elixir")
"""
[:get, :post, :delete, :head, :patch, :run]
|> Enum.each(fn req_method ->
@doc """
#{req_method |> to_string |> String.capitalize()} request
## Example
iex> ReqClient.#{req_method} "https://httpbin.org/#{req_method}"
"""
def unquote(req_method)(url, opts \\ []) do
opts =
opts
|> Keyword.put_new(:url, url)
|> new()
apply(Req, unquote(req_method), [opts])
end
bang_method = "#{req_method}!" |> String.to_atom()
@doc """
#{req_method |> to_string |> String.capitalize()} request with direct response
## Example
iex> ReqClient.#{bang_method} "https://httpbin.org/#{req_method}"
"""
def unquote(bang_method)(url, opts \\ []) do
opts =
opts
|> Keyword.put_new(:url, url)
|> new()
apply(Req, unquote(bang_method), [opts])
end
end)
@doc """
Build a new Req client
- deps/req/lib/req.ex
- https://hexdocs.pm/req/Req.html#new/1
"""
def new(opts \\ []) do
default_opts()
|> Req.new()
# NOTE: prepend in reversed order
|> ReqClient.Proxy.attach()
|> ReqClient.Breaker.attach()
|> ReqClient.TraceId.attach()
|> ReqClient.Timing.attach()
|> ReqClient.Inspect.attach()
|> ReqClient.Verbose.attach()
|> ReqClient.Stub.attach()
|> Req.merge(opts)
end
@doc """
More options from https://hexdocs.pm/req/Req.html#new/1-options
"""
def default_opts() do
[
# default is 10
max_redirects: 5,
# timeout in milliseconds
pool_timeout: 5_000,
receive_timeout: 15_000,
connect_options: [
# timeout defaults to 30_000
timeout: 30_000
# transport_opts: [
# # Issue: (ArgumentError) unknown application: :castore in escript
# # default verify strategy
# # verify: :verify_peer
# # cacerts: :public_key.cacerts_get()
# verify: :verify_none
# ],
# # not works direct with socks5h here!!!
# # use below from https://github.com/oyyd/http-proxy-to-socks
# # hpts -s 127.0.0.1:1080 -p 8080
# proxy: {:http, "localhost", 1087, []}
]
]
end
## Utils
def find_option(req, options \\ []) do
options
|> Enum.find_value(fn op ->
Req.Request.get_option(req, op)
end)
end
def default_req_opts do
Req.default_options()
end
@doc """
iex> url = "https://elixir-lang.org"
iex> Req.get!(url, cache: true)
$> ls -al ~/Library/Caches/req
"""
def cache_dir, do: :filename.basedir(:user_cache, ~c"req")
## finch
def finch_children(sup \\ Req.FinchSupervisor) do
# {DynamicSupervisor, strategy: :one_for_one, name: Req.FinchSupervisor},
# dynamic create pool when provided :connect_options: []
DynamicSupervisor.which_children(sup)
end
@doc """
protocols: [:http1]]
Req.Finch default pool not support proxy!!!
"""
def default_finch_opts do
# Req default start Finch pool
# {Finch, name: Req.Finch, pools: %{default: Req.Finch.pool_options(%{})}}
Req.Finch.pool_options(%{})
end
end