@jdiaz the terminology comes directly from the “Server as a Function” paper, of which http4k and Finagle are implementations/adaptions since http4k dropped the Futures and the generics). Middleware is probably a better term - we also did think about calling it Pipe, but eventually decided to stick with the official name. As for “only one filter can exist”, that’s a misunderstanding - I’m not sure I’m explaining myself properly. :) The ReportHttpTransaction Filter is
just a function that takes a request, calls down to the next handler in the chain (which could be another Filter or an HttpHandler), gets a response, creates an HttpTransaction, and then passes that to firstly the labeller and secondly the report function. Hence each instance of that filter is creating a different transaction object, the receiver of which will only be the reporting function of that same filter instance. The usage of the request context is actually functionally impure because we’re effectively using the RequestContexts as an external vehicle for carrying information outside of the filter chain - no info is actually added to the request object - but the request itself is used as a key to retrieve the info later (in this case your label).
The main point is that composing filters (functions) together forms a call chain ( like a ServletFilter) which eventually terminates in an HttpHandler (also a function). It’s better explained here TBH 😀
https://monkey.org/~marius/funsrv.pdf