-
Notifications
You must be signed in to change notification settings - Fork 731
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 HTTPNetworkTransportDelegate and HTTPNetworkTransportInterception #297
Add HTTPNetworkTransportDelegate and HTTPNetworkTransportInterception #297
Conversation
So that mutating headers and other inspection can be done by the delegate. This means being able to change headers without recreating clients or logging request/response timing at a high level by instrumenting the calls to the interception. Functionality this should give callers adequate control over the http pipeline. By using an `Interception` to encapsulate state it would be easy to implement a timer for a request/response pair. By flattening it into the delegate itself that information would be lost without using a unique id to tie them together. Alternatively one could implement http chaining like seen in okhttp which would give a cleaner contract in terms of showing that only one call to `Chain.proceed` can perform an interception but is ultimately more complicated.
@brennantaylor: Thank you for submitting a pull request! Before we can merge it, you'll need to sign the Meteor Contributor Agreement here: https://contribute.meteor.com/ |
WOW!. this is awesome |
This is great! I'd love to be able to update the client auth headers without recreation. |
@brennantaylor I would really like us to get a solution for this over the finish line. Thanks for opening this PR. One thing missing from this solution is support for asynchronous callbacks. I think that is a hard requirement to implement use cases like retries on errors and token refresh (see the Alamofire RequestRetrier for an example of this). There is an existing PR that deals with this. Maybe we can continue the discussion there to keep everyone involved. Definitely open to exploring an interception mechanism as an alternative to a delegate as well. We have something similar in JavaScript (Apollo Link), and that has proven to be a very fruitful extension mechanism. There is an existing PR that tried to explore this. |
@brennantaylor I would love for this to make it into master soon! This is exactly what i need :) |
@@ -41,11 +41,24 @@ public struct GraphQLHTTPResponseError: Error, LocalizedError { | |||
} | |||
} | |||
|
|||
/// Used to intercept the http requests/errors/responses. This allows modifying url requests dynamically without recreating transports | |||
public protocol HTTPNetworkTransportDelegate: class { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm using this directly on the application level to verify if this works for various use cases.
Question: what is the reason for this protocol - it looks like the only responsibility is to create interception for each request.
|
||
/// An encapsulation of state for a single request (response/error) pair. If any method returns non-null it will be used in the http pipeline | ||
public protocol HTTPNetworkTransportInterception { | ||
func willSend(request: URLRequest) -> URLRequest? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When using willSend I can access request fields but I cannot add headers (request is immutable object)
I have done some investigations with this by trying to write Alamofire version of the NetworkTransport. What is currently blocking users from IOS is that essential parts that are required to write your own NetworkTransport are not available. Some classes used in apollo network transport are internal - means that when writing your own version of it it will not be possible to reuse them. IMHO easy fix will be to make change This PR provides some level of flexibility, but allowing users to write their own NetworkTransport will be ultimate fix that will support all use cases. [1] apollo-ios/Sources/Apollo/HTTPNetworkTransport.swift Lines 140 to 149 in 2bd859d
|
/// A network transport that uses HTTP POST requests to send GraphQL operations to a server, and that uses `URLSession` as the networking implementation. | ||
public class HTTPNetworkTransport: NetworkTransport { | ||
let url: URL | ||
let session: URLSession | ||
let serializationFormat = JSONSerializationFormat.self | ||
public weak var delegate: HTTPNetworkTransportDelegate? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I might miss the usage for this, but when testing this I needed to drop weak
keyword to make everything work.
This keyword may be not needed here (although I might miss some context that author had when doing this)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Delegates should be weak to avoid reference cycles. As recommended in the SwiftLint rules.
Hi! Whats the status on this request? I would really need this feature for my use case. Whats blocking this from getting approved? |
@naknut There are couple PR's currently open with similar approaches. |
Any update on this? @wtrocki @brennantaylor @naknut Lots of open issues and PRs for similar functionality, so would be great to get something merged in |
@theadactyl There seem to be no interest to get the solution for this merged inside the apollo-ios. There are more than couple PR's solving the same issue. This just does the job and adding it to documentation will be quite handy as many people asking for it. |
Hey @brennantaylor - Thank you for doing this, and sorry for the long radio silence on our end! Unfortunately since so much has changed since this PR was opened, I'm going to close this in favor of the work happening in #602 to implement this feature. Please feel free to chime in there if you have thoughts or questions, and open issues on anything you feel we may be leaving out. |
Add HTTPNetworkTransportDelegate and HTTPNetworkTransportInterception
So that mutating headers and other inspection can be done by the delegate. This
means being able to change headers without recreating clients or logging
request/response timing at a high level by instrumenting the calls to the
interception. Functionality this should give callers adequate control over the
http pipeline.
By using an
Interception
to encapsulate state it would be easy to implement atimer for a request/response pair. By flattening it into the delegate itself
that information would be lost without using a unique id to tie them together.
Alternatively one could implement http chaining like seen in okhttp which would
give a cleaner contract in terms of showing that only one call to
Chain.proceed
can perform an interception but is ultimately more complicated.