hackney_middleware (hackney v4.0.2)

View Source

RoundTripper-style middleware for hackney:request/1..5.

A middleware is a fun fun((Request, Next) -> Response). Next is itself a fun that takes a (possibly rewritten) request and returns the response. Middleware can observe, rewrite, short-circuit, or wrap the downstream call.

Chains are outermost-first: [A, B, C] means A wraps B wraps C, so the request flows A -> B -> C -> transport and the response unwinds the same way. This matches Go's http.RoundTripper, Plug, Rack and Tower-rs.

Middleware wraps the user-facing hackney:request/1..5 only. The low-level hackney:connect/* + hackney:send_request/2 path is intentionally unchanged.

Example — a minimal duration logger:

   Log = fun(Req, Next) ->
       T0 = erlang:monotonic_time(millisecond),
       Resp = Next(Req),
       logger:info("~p ~s -> ~pms",
                   [maps:get(method, Req),
                    hackney_url:unparse_url(maps:get(url, Req)),
                    erlang:monotonic_time(millisecond) - T0]),
       Resp
   end,
   hackney:get(URL, [], <<>>, [{middleware, [Log]}]).

Summary

Functions

Apply Chain (outermost-first) around Terminal.

Pick the middleware chain for a request.

Types

middleware/0

-type middleware() :: fun((request(), next()) -> response()).

next/0

-type next() :: fun((request()) -> response()).

request/0

-type request() ::
          #{method := atom() | binary(),
            url :=
                #hackney_url{transport :: atom(),
                             scheme :: atom() | binary(),
                             netloc :: binary(),
                             raw_path :: binary() | undefined,
                             path :: binary() | undefined | nil,
                             qs :: binary(),
                             fragment :: binary(),
                             host :: string(),
                             port :: integer() | undefined,
                             user :: binary(),
                             password :: binary()},
            headers := [{binary(), binary()}],
            body := term(),
            options := [term()]}.

response/0

-type response() ::
          {ok, integer(), list(), binary()} |
          {ok, integer(), list()} |
          {ok, reference()} |
          {ok, pid()} |
          {error, term()}.

Functions

apply_chain(Chain, Req, Terminal)

-spec apply_chain([middleware()], request(), next()) -> response().

Apply Chain (outermost-first) around Terminal.

The returned response is whatever the outermost middleware produces; crashes propagate to the caller.

resolve_chain(Options)

-spec resolve_chain([term()]) -> [middleware()].

Pick the middleware chain for a request.

Per-request {middleware, List} in Options replaces the global application:get_env(hackney, middleware) value. No implicit merge.