I am trying to write a middleware that will set additional params to the query string. The use case is to be able to add additional authentication tokens, for eg, to the request as required by the backend, but wanting to inject it independent of the request creation itself.
This is what my middleware(pseudo code) looks like:
class MyMiddleware < Struct.new(:app, :key, :value)
def call(env)
env.params[key] = value #1
#env.params = {key => value} #2
app.call env
end
end
- above raises NoMethodError (undefined method[]=' for nil:NilClass)`
- above sets the params hash but the parameter is not encoded as part of the query string. The query string remains what it was before the middlewares start processing the request.
My analysis is that since the query string gets built from the params in rack_builder.rb:191
def build_response(connection, request)
app.call(build_env(connection, request))
end
def build_env(connection, request)
Env.new(request.method, request.body,
connection.build_exclusive_url(request.path, request.params), #<== rack_builder.rb:191
request.options, request.headers, connection.ssl,
connection.parallel_manager)
end
Middlewares don't get the opportunity to set additional params. While env has a params property, it is nil and doesn't appear to be touched during or after the middlewares get invoked.
So, I have the following questions: 1. Is there a supported way to achieve this? 2. If not, is there a way to rebuild the query string as part of the middleware executing? 3. Would it be better to defer the URL building to after most of the request middleware chain is executed (but of course, before the adapter gets to do its thing; or do it in the adapter)? 4. Any other options?
Appreciate any guidance.
The answer is here at github: https://github.com/lostisland/faraday/issues/483 by @mislav