@type client_opts() :: map()
@type req_params() :: %{url: String.t(), method: atom(), body: map()}
@spec request(req_params(), client_opts()) :: struct() | {:error, term()}