Skip to content

Add Finch HTTP client and make hackney an optional dependency#151

Open
klacointe wants to merge 1 commit into
elixir-waffle:masterfrom
klacointe:feat/optional-hackney-dependency
Open

Add Finch HTTP client and make hackney an optional dependency#151
klacointe wants to merge 1 commit into
elixir-waffle:masterfrom
klacointe:feat/optional-hackney-dependency

Conversation

@klacointe

@klacointe klacointe commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #150. Revives the Finch client from the closed #148 (which was split up to keep that PR scoped to the adapter pattern), and completes the original goal: making :hackney an optional dependency now that a real alternative exists.

  • Add Waffle.HTTPClient.Finch, guarded with Code.ensure_loaded?(Finch) — the implementation is carried over unchanged from Add pluggable HTTP client behaviour with Hackney and Finch implementations #148.
  • Make :hackney optional: true. Since it remains the default configured client, Waffle.HTTPClient.Hackney is still always defined, but guarded with Code.ensure_loaded?(:hackney); if it's missing, calling it raises a clear, actionable error instead of a bare UndefinedFunctionError.
  • Extract parse_content_disposition/1 onto the Waffle.HTTPClient behaviour so both clients (and any custom implementation) share one parser, instead of Hackney depending on the internal :hackney_headers module.
  • Bump CI's Dockerfile to elixir:1.17-alpine (Finch requires Elixir ~> 1.15).
  • Document both clients and the "at least one HTTP client dependency is required" story in the README/CHANGELOG.

Configuration

# Hackney (default) — add {:hackney, "~> 1.9"} to deps
config :waffle, :http_client, Waffle.HTTPClient.Hackney

# Finch — add {:finch, "~> 0.18"} to deps, start a pool, then:
config :waffle, :http_client, Waffle.HTTPClient.Finch
config :waffle, Waffle.HTTPClient.Finch, pool_name: MyApp.Finch

Notes

  • No default behaviour change for existing users — hackney remains the default client.
  • Finch has no fallback/raise stub if missing (unlike Hackney), since it's never silently defaulted to — you only reach it by explicitly configuring :http_client, so a bare UndefinedFunctionError naming the module you just typed is already self-diagnosing.

Tests

  • New tests for Waffle.HTTPClient.Finch (mocked transport layer, redirects, body-size limiting, timeouts)
  • New tests for the shared parse_content_disposition/1 helper
  • Updated an existing store_test.exs test that relied on hackney's internal header-parsing API

@klacointe klacointe force-pushed the feat/optional-hackney-dependency branch 2 times, most recently from 1af66b8 to 8b3cc7a Compare July 2, 2026 19:22
- Add Waffle.HTTPClient.Finch, ported from the closed elixir-waffle#148 (already
  survived two rounds of review there), guarded with
  Code.ensure_loaded?(Finch) so it compiles out when finch isn't a dep
- Make :hackney optional: true; guard Waffle.HTTPClient.Hackney with
  Code.ensure_loaded?(:hackney) and raise a clear, actionable error if
  it's the (default) configured client but the dependency is missing
- Extract parse_content_disposition/1 onto the Waffle.HTTPClient
  behaviour so both clients (and custom implementations) share one
  parser instead of Hackney depending on the internal :hackney_headers
  module
- Bump CI's Dockerfile to elixir:1.17-alpine (finch requires ~> 1.15)
- Bump credo to ~> 1.7; ~> 1.4's tokenizer crashes under Elixir 1.17+
- Add @moduledoc false to Mix.Tasks.Waffle; credo 1.7 newly flags it
  as missing, unlike 1.6
- Update README/CHANGELOG to document both clients and the "at least
  one is required" dependency story
@klacointe klacointe force-pushed the feat/optional-hackney-dependency branch from 8b3cc7a to 58a4d41 Compare July 2, 2026 19:35
@klacointe klacointe marked this pull request as ready for review July 2, 2026 19:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant