在法拉第中间件中添加params

时间:2015-06-26 14:16:07

标签: faraday

我正在尝试编写一个中间件,它将为查询字符串设置其他参数。用例是能够添加额外的身份验证令牌,例如,根据后端的要求添加请求,但是想要独立于请求创建本身注入它。

这是我的中间件(伪代码)的样子:

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
    上面的
  1. 引发NoMethodError(未定义的方法[] =&#39;对于nil:NilClass)`
  2. 上面设置了params散列,但参数不是作为查询字符串的一部分编码的。查询字符串保持中间件开始处理请求之前的状态。
  3. 我的分析是,因为查询字符串是从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
    

    中间件没有机会设置额外的参数。虽然env具有params属性,但它是零并且在调用中间件期间或之后似乎没有触及。

    所以,我有以下问题: 1.是否有支持的方法来实现这一目标? 2.如果没有,有没有办法重建查询字符串作为中间件执行的一部分? 3.在执行大多数请求中间件链之后将URL构建推迟到更好(但当然,在适配器执行其操作之前;或者在适配器中执行此操作)? 4.还有其他选择吗?

    感谢任何指导。

1 个答案:

答案 0 :(得分:1)

答案在@islav

的github:https://github.com/lostisland/faraday/issues/483
  

在中间件中,请求URL已与字符串中的所有已配置查询参数一起完全构建。添加或删除查询参数的唯一方法是编辑env.url.query字符串,例如:

MyMiddleware = Struct.new(:app, :token) do
  def call(env)
    env.url.query = add_query_param(env.url.query, "token", token)
    app.call env
  end

  def add_query_param(query, key, value)
    query = query.to_s
    query << "&" unless query.empty?
    query << "#{Faraday::Utils.escape key}=#{Faraday::Utils.escape value}"
  end
end

conn = Faraday.new "http://example.com" do |f|
  f.use MyMiddleware, "MYTOKEN"
  f.adapter :net_http
end
  

但是,如果您的中间件将类似于上面的MyMiddleware并且只是为所有请求添加静态查询参数,则更简单的方法是避免使用中间件并仅配置法拉第连接实例以将相同的查询参数应用于所有请求:

conn = Faraday.new "http://example.com" do |f|
  f.params[:token] = "MYTOKEN"
  f.adapter :net_http
end