-
Notifications
You must be signed in to change notification settings - Fork 966
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
Add ability to query builder/connection to see if they contain an adapter. #170
Conversation
Shebang with more than one argument is not portable. See e.g. http://stackoverflow.com/questions/570183/can-i-use-perls-switches-with-bin-env-in-the-shebang-line
|
On Tue, Jun 19, 2012 at 5:54 PM, Mislav Marohnić <
Ones that I'm building in Leadlight.
Because env doesn't permit more than one argument on most unixen. Read the
I deliberately set things up so that wouldn't be the case. What did I miss? |
|
Leadlight enables client code to provide its own middleware stack. If the As far as I can tell I can't rely on Faraday for this because it only adds |
On Tue, Jun 19, 2012 at 6:01 PM, Mislav Marohnić <
See my last reply. I'm not building them; I'm providing a hook for
This is the code I added to def adapter?
klass.respond_to?(:adapter?) && klass.adapter?
end Is that not sufficient? |
To make things a little more concrete, here's a sample of a real Leadlight service definition: class GithubService
Leadlight.build_service(self) do
url 'https://api.github.com'
build_connection do |c|
c.adapter :typhoeus
end
tint 'root' do
match_path('/')
add_link_template '/users/{login}', 'user', 'Find user by login'
end
tint 'auth_scopes' do
extend do
def oauth_scopes
__response__.headers['X-OAuth-Scopes'].to_s.strip.split(/\W+/)
end
end
end
end
def prepare_request(request)
request.headers['Authorization'] = "Bearer #{options[:oauth2_token]}"
end
end The important bit is the |
Whoops, missed the I'm giving you a hard time, but not explaining why. Basically, I'm not happy with the concept of adapters we have now, and I want to change this for the next release. So I'm not eager to make changes that just tweak the current situation—I want to radically rethink the whole thing, as per #47. Adapters are middleware right now, but that's just wrong:
My idea is to redesign Faraday::Connection to start with default adapter, offer you to customize the middleware stack, but if you don't specify an explicit adapter, it will just keep using the default one. Also, adapters would then be "Rack endpoints", not middleware. This is a significant change, but would be perfectly backwards compatible with any userland code. This would solve your problem since you could then initialize a Connection with an adapter of your choice, and let the user customize their middleware stack, but they can choose to leave out the adapter. |
One final clarification: when I say that client code can add its own middleware stack, I mean that it can augment the stack. Leadlight has some middlewares that it will always add regardless of what the client code adds. |
FWIW, I completely agree with this long-term direction. Having adapters as middlewares is confusing and error-prone. I feel like most of this changeset is compatible with your rewrite: it seems to me that it would still make sense to ask an connection if its adapter slot has been filled. The only difference would be that there'd no longer be a need to iterate over the middleware list to answer that question. Thoughts? |
There won't be a need to ask a connection if it has an adapter, since it won't be possible to have a connection without an adapter. So, this changeset doesn't actually help with this goal :(
How are you adding this middleware? I'm interested in how 3rd party libs allow users to customize the stack, while still forcing middleware of their own. It can be tricky/brittle, so I'm wondering if there's something we can improve about this. (This is actually not much related to our original discussion.) |
So a connection without an adapter will be invalid? |
You won't be able to have a connection without an adapter. At instantiation, it would inherit Faraday.default_middleware. While building the middleware stack, you can override adapter the usual way. Even after the stack was setup, you will be able to change adapter with |
…the stack. - Connection#adapter= clears ALL adapters from the stack and adds a new one at the bottom. - The `:adapter` option to `Connection#new` forces the given adapter options to be used, if provided. - `Connection#adapter` with no arguments now returns the first adapter found in the stack.
Try the above commit on for size. It's an attempt at adding an API that separates the adapter from the rest of the stack, without actually changing anything internally (yet) or introducing backwards-incompatibilities. See the full commit message for details. |
Interesting. I'll look at this again when it's not 2am, let you know what I think I have a feeling that it can be done without so many changes to Builder, but I might be wrong (theory is always easier than code) |
As an aside, I was thinking as I worked on this that a Builder is a fundamentally separate concept from the thing being built (a handler stack). Would you be interested in a commit that separates the two? |
This separation would be correct, theoretically, but I'm not sure it would benefit us much. Builder isn't an area where we spend a significant amount of development time, or plan to spend for that matter. My idea: remove the concept of an adapter from Builder / middleware stack. As I said, adapters will be endpoints not middleware. This change would be breaking for anyone calling #adapter on a builder instance but most people are calling #adapter on connection since that's what's yielded from Faraday::Connection.new. Adapters would be handled by Connection here: https://github.com/technoweenie/faraday/blob/master/lib/faraday/connection.rb#L117-127 That also means this awkward lambda with Response handling will go away, yay (will be done inside each individual middleware) |
Interesting discussion. I've dealt with some of the same issues in my usage of Faraday, so I'll chime in a bit here :).
I've seen this in the wild, too--it was actually the source of a VCR bug I had to track down--the instagram gem put a middleware after an adapter and it screwed things up for VCR's faraday middleware.
I've done this a couple of ways:
Silo::Client.configure do |config|
config.middleware do |builder|
builder.insert 0, MyCoolMiddleware
end
end |
On Wed, Jun 20, 2012 at 12:09 AM, Myron Marston <
Hah, yeah a lot of this stemmed from going through and eliminating your |
Hello everyone, I can see this PR have been open for quite a long time. I'm sorry to close this after having it open for so long, all this discussion will be useful to decide how to address this issue the right way in v1.0 |
I want this in Leadlight so I can optionally add a default adapter if there isn't one already.