Salemove.HttpClient

Build StatusHex.pmDocumentation

Elixir HTTP client for JSON services built on top of tesla.

Installation

The package can be installed by adding salemove_http_client to your list of dependencies in mix.exs:

def deps do
[
{:salemove_http_client, "~> 6.0"},
{:finch, "~> 0.23"}
]
end

Documentation can be found at https://hexdocs.pm/salemove_http_client.

Usage

defmodule GihubClient do
use Salemove.HttpClient,
base_url: "https://api.github.com/"
end

Requests are made through Tesla.Adapter.Finch by default, backed by a Finch pool that this library starts itself (named Salemove.HttpClient.Finch) — no supervision tree changes are needed. The pool is only started when :finch is available and the adapter configured via the :salemove_http_client application environment resolves to Tesla.Adapter.Finch (the default); applications configured with another adapter don't run an unused pool.

The pool can be tuned via the :finch_pools application environment.

Pay attention to setting a pool's size; it's a hard cap on concurrent requests per scheme, host and port.

The following custom configuration is an example that would make no difference because it matches this library's defaults.

If you pass any Tesla options, none of the defaults (except for :finch_pools) will apply. If you pass :finch_pools, the default :finch_pools value won't apply.

config :salemove_http_client,
adapter: Tesla.Adapter.Finch,
adapter_options: [
name: Salemove.HttpClient.Finch,
receive_timeout: 4500
],
retry: false,
finch_pools: %{
default: [conn_max_idle_time: 30_000, conn_opts: [transport_opts: [timeout: 1_500]]]
}

Migrating from 5.x to 6.0

The default adapter changed from Tesla.Adapter.Hackney to Tesla.Adapter.Finch, and the library now starts its own default Finch pool, so no supervision tree changes are needed.

Add finch to your dependencies

Finch is an optional dependency of this library. To use the default adapter, add it yourself:

{:finch, "~> 0.23"}

If tesla was already compiled before finch was added, recompile it so the Finch adapter is included: mix deps.clean tesla && mix deps.compile tesla. Without finch, the default pool is not started and requests fail.

For HTTPS, make sure castore is in your dependency tree — Mint uses it for CA certificates and raises on HTTPS requests without it:

{:castore, "~> 1.0"}

TLS peer verification is now on by default

The previous hackney default (no ssl_options) performed no certificate verification. Finch/Mint verify the peer by default against the castore CA bundle, so requests to endpoints served with a private or internal CA — which silently succeeded under 5.x — will now fail. Trust the CA on the default pool:

config :salemove_http_client,
finch_pools: %{default: [conn_opts: [transport_opts: [cacertfile: "/path/to/ca.pem"]]]}

or, if you must, opt out of verification:

config :salemove_http_client,
finch_pools: %{default: [conn_opts: [transport_opts: [verify: :verify_none]]]}

Consider a custom pool size

Finch creates separate pools for each {scheme, host, port} combination and each pool has a hard limit on concurrent requests, dictated mainly by the pool's :size.

This library uses Finch's default :size.

If you want to avoid full pools, consult your service's metrics and set the :size comfortably above the max observed count of concurrent outgoing requests.

config :salemove_http_client,
finch_pools: %{default: [size: 200], smaller_kind_of_pool: [size: 20]}

Audit your adapter_options — they are NOT translated

Adapter options are passed to the adapter verbatim and are adapter-specific. Tesla.Adapter.Finchsilently ignores options it does not recognise, so hackney-style options left over from 5.x do not fail loudly — they simply stop having any effect. Check every config :my_app, MyClient entry and every use Salemove.HttpClient option list:

Hackney option (5.x)With the Finch adapter (6.0)
recv_timeout: 4500Rename to receive_timeout: 4500. If left unrenamed, requests silently run with Finch's default receive timeout of 15 000 ms instead.
connect_timeout: 1500Remove; configure at pool level via :finch_pools (conn_opts: [transport_opts: [timeout: 1_500]]). The previous 1500 ms default is preserved in the default pool.
ssl_options: [...]Remove; configure at pool level via :finch_pools (conn_opts: [transport_opts: [...]]). Note that Finch/Mint verify TLS peers by default, using CA certificates from the castore package — see "Add finch to your dependencies" above.
pool: :my_poolRemove; Finch selects pools by request URL. For a dedicated pool, start your own named Finch instance (see below).
proxy: ...Not supported per-request; see the proxy section below.

The :salemove_http_client application environment is now read at request time, so it can be set in config/runtime.exs and config changes no longer require recompiling the dependency.

You also need to act if any of the following applies:

Note that any options passed to :finch_pools will override this library's default pool settings (see Usage).

Migrating from 1.x to 2.0

Module config is now deep merged with base salemove_http_client config, so when upgrading, make sure that calls to Salemove HTTP Client don't rely on the configuration being shallow merged.

Example

config :foo, Some.Module,
adapter_options: [
connect_timeout: 8000
]
config :salemove_http_client,
adapter_options: [
ssl_options: [verify: :verify_none]
]

and as a result of

use Salemove.HttpClient, Application.fetch_env!(:foo, Some.Module)

with the older version the configuration would have been:

adapter_options: [
connect_timeout: 8000
]

with 2.x and upwards it is:

adapter_options: [
ssl_options: [verify: :verify_none],
connect_timeout: 8000
]

To disable stats now, you can just set stats value to false in the module configuration.

Migrating from 0.x to 1.0

Most changes are due to changes in Tesla HTTP client. Migrating guide for tesla can be seen at https://github.com/teamon/tesla/wiki/0.x-to-1.0-Migration-Guide.

Changes specific to Salemove HTTP Client

License

MIT License, Copyright (c) 2017 SaleMove