Faraday: Help writing middleware

Created on 21 Jan 2014  ·  13Comments  ·  Source: lostisland/faraday

It seems to me from the documentation that the following should work. But it doesn't. The docs are poor for writing middleware. In lieu of that can someone lend some assistance.

# play.rb
require 'faraday'

class MyMiddleware

  attr_reader :options

  def initialize(app, options={})
    @app = app
    @options = options
  end

  def call(env)
    @app.call(env)
  end

end

# This doesn't seem to work either, removing for now.
# Faraday.register_middleware :request, my_middlware: lambda { MyMiddleware }

client = Faraday.new do |conn|
  # conn.request :my_middleware, foo: :bar
  conn.request MyMiddleware, foo: :bar
end

response = client.get('http://jasonwaldrip.com/')
$ ruby play.rb
/Users/jwaldrip/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/faraday-0.8.9/lib/faraday.rb:64:in `lookup_middleware': MyMiddleware is not registered on Faraday::Request (RuntimeError)
    from /Users/jwaldrip/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/faraday-0.8.9/lib/faraday/builder.rb:146:in `use_symbol'
    from /Users/jwaldrip/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/faraday-0.8.9/lib/faraday/builder.rb:100:in `request'
    from play.rb:19:in `block in <main>'
    from /Users/jwaldrip/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/faraday-0.8.9/lib/faraday/connection.rb:65:in `initialize'
    from /Users/jwaldrip/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/faraday-0.8.9/lib/faraday.rb:11:in `new'
    from /Users/jwaldrip/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/faraday-0.8.9/lib/faraday.rb:11:in `new'
    from play.rb:18:in `<main>'

Most helpful comment

A full simple example would go a long way for the documentation.

All 13 comments

Try conn.use instead of conn.request. It's trying to look the MyMiddleware middleware in Faraday::Request.

https://github.com/lostisland/faraday/blob/b8d90a59bafb8dd6e19488fae07945a7700f5664/lib/faraday/rack_builder.rb#L82-L101

@technoweenie We should have better documentation for how to register middleware. I recently had to do it here and had to read the code to figure out how.

@jwaldrip If you had registered your middleware, you’d be able to say conn.request.

If you had registered your middleware, you’d be able to say conn.request.

Also, you should use the symbol that you registered with, not the class name. The symbols are only there as a shortcut to including the full class name. conn.request(:json) is basically the same as Faraday::Request::JSON.

We should have better documentation for how to register middleware.

:+1: I pushed it off because I planned to completely change the middleware system.

@jwaldrip Is right that this is poor user experience. He commented out the line that registers the middleware under a symbol shorthand, but continued to use conn.request setter which only works with symbol shorthands I think. Therefore the middleware couldn't be found.

We should think how to improve that, or at least have a better error message.

I got it working, took some time. Let me know if I can help at all with documentation or the middleware rework.

What did you final setup look like? @jwaldrip

Was there ever anything written up around this? I could not find anything useful and had to bash my head for a few minutes to figure it out.

@stefansedich not sure if there was any direct follow up or improvement after this discussion, but we're planning to do some heavy work on the documentation together with the next major release (1.0) so hopefully this won't be a problem in future again.

Would be great if someone posted what exactly registering looks like in this issue for now.

@maxim We now have an official website with some documentation around middleware, however it's still improving.

In short, request and response should only be used for registered middleware, if you need to inject a custom-built one is just easier to call .use.
So in the example above, the following would work:

client = Faraday.new do |conn|
  conn.use MyMiddleware, foo: :bar
end

A full simple example would go a long way for the documentation.

@maxim We now have an official website with some documentation around middleware, however it's still improving.

In short, request and response should only be used for registered middleware, if you need to inject a custom-built one is just easier to call .use.
So in the example above, the following would work:

client = Faraday.new do |conn|
  conn.use MyMiddleware, foo: :bar
end

@iMacTia That's not in the documentation but it is essential. Perhaps it could be in https://lostisland.github.io/faraday/middleware/custom

@wilsonsilva you're totally right, that would definitely be a good improvement 😅. I'm surprised it was missed to be fair

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mattmill30 picture mattmill30  ·  4Comments

ryanbyon picture ryanbyon  ·  3Comments

jedeleh picture jedeleh  ·  3Comments

iMacTia picture iMacTia  ·  3Comments

jordansissel picture jordansissel  ·  5Comments