New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Question: How to add a default middleware to all faraday client instances? #946
Comments
@danielgatis I'm afraid this is currently not possible. If you you're not abusing connection and still need this in place, you have a couple of options.
def shared_stack(conn)
conn.request :url_encoded
conn.use MyMiddleware
conn.adapter Faraday.default_adapter
end
conn1 = Faraday.new(url1) { |conn| shared_stack(conn) }
conn2 = Faraday.new(url2) { |conn| shared_stack(conn) }
Faraday.default_connection = Faraday.new do |conn|
conn.request :url_encoded
conn.use MyMiddleware
conn.adapter Faraday.default_adapter
end
# Now that you setup a default connection, you can simply call the urls without creating a new connection every time
Faraday.get(url1)
Faraday.get(url2) Let me know if any of the above helps |
Thanks for help @iMacTia. |
I needed to do this too and after much searching, came across this issue. In my case, I was testing an APM service. I have a number of API client gems in my app. I know they all use Faraday. So I was hoping to just be able to set it up so any connection would get the APM Middleware. I do think this is a legit use case. For my own testing purposes I did the following evil monkey patch: module Faraday
class Connection
alias_method :orig_initialize, :initialize
def initialize(url = nil, options = nil)
orig_initialize(url, options)
yield self if block_given?
builder.use :apm_thingymagick_here
end
end
end I do not recommend this, but if anyone else finding this issue needs a quick temporary solution, this works for now... you will get the following warning which indicates it will stop working at some point in the future:
|
+1 for the above. An APM is the only use case I've seen code a default middleware. For example see datadog's APM They suggest to do something like this:
If you don't add the |
@marcheiligers @doliveirakn I know this sounds like a reasonable and simple use case, but in reality it's actually more complicated than what it looks like. In short, it is something only "pro" users should do and only if they understand what they're actually doing. As things stand, we don't feel like this should be a feature provided by Faraday and available to everyone and I'd ask you to stick with the Monkey Patch you proposed. |
I get that the middleware order is really important. I think it would be really nice to be able to provide a way to flag middleware as default when registering it, and then when a new builder is made, applying the default middleware first (so it is the outermost), and then any custom middleware and then finally the adapter. For other's that may require this behaviour, this is the "fix" that I took to get this to work within our stack so that the module FaradayConnectionOptions
def new_builder(block)
super.tap do |builder|
builder.use(:ddtrace)
end
end
end
Faraday::ConnectionOptions.prepend(FaradayConnectionOptions) |
@doliveirakn thanks for sharing that snippet, that is exactly the way we could implement it in Faraday as well, probably by letting you define a list of "default_middlewares" as a global setting in Faraday (similar to However as you pointed out we need to decide where the middleware should be injected, with you suggesting to go for the top. That might work for your specific use case, however it won't work for others. For example, I might want to send all requests to a logging/monitoring service, however injecting such a middleware at the beginning will cause parameters not to be encoded and middleware that changes the request (e.g. setting headers) won't have run yet, causing the logged request to be incomplete. So then we would be asked to change the implementation allowing to choose if the middleware should go at the beginning or the end (still doable). That's it, until someone finds a use case where they need the middleware to be positioned in an exact position to avoid conflicts. Even worse, you might inject a middleware that causes the stack to fail, potentially causing developers to open issue on the gem that builds that stack using Faraday, even though they have no clue of why that happens. So here is our take on this:
|
Kind of in the same situation. Would like to enable the shipped instrumentation middleware for all Faraday connections. The use case is to instrument external requests made by other gems we do not control. In this case, the I do agree that the best solution would be for these gems to allow configuring the Faraday stack. |
Hi,
How is the correct way to add a default middleware to all faraday client instances?
Example:
My middleware:
My clients:
I expected that all my clients (conn1, conn2) use MyMiddlware as default.
The text was updated successfully, but these errors were encountered: