-
Notifications
You must be signed in to change notification settings - Fork 64
[v2] [12/X] ApolloClient Fetch APIs #684
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
base: v2-ClientContext
Are you sure you want to change the base?
Conversation
For retrying a failed request, allowing interceptor to inspect & change the fetch behavior is useful.
@@ -76,25 +52,31 @@ public final class ApolloClient: ApolloClientProtocol, Sendable { | |||
/// - networkTransport: A network transport used to send operations to a server. | |||
/// - store: A store used as a local cache. Note that if the `NetworkTransport` or any of its dependencies takes | |||
/// a store, you should make sure the same store is passed here so that it can be cleared properly. | |||
/// - defaultCachePolicy: TODO | |||
/// - clientAwarenessMetadata: Metadata used by the |
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.
Needing documentation for the new defaultRequestConfiguration
parameter.
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.
Yes, I've been changing some of the docs as I go, but we'll need to do a full documentation audit prior to public release.
/// - Parameter url: The URL of a GraphQL server to connect to. | ||
/// - Parameters: | ||
/// - url: The URL of a GraphQL server to connect to. | ||
/// - clientAwarenessMetadata: Metadata used by the |
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.
Needing documentation for the new defaultRequestConfiguration parameter.
Same here..
@@ -26,6 +26,7 @@ public struct AutoPersistedQueryConfiguration: Sendable, Hashable { | |||
|
|||
public protocol AutoPersistedQueryCompatibleRequest: GraphQLRequest { | |||
|
|||
#warning("Consider moving this to ClientContext or RequestConfiguration?") |
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.
RequestConfiguration
seems like a good home for this based on the scope/behaviour we discussed yesterday.
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.
The way RequestConfiguration
works, the values are just passed to the NetworkTransport
which then uses them when constructing the GraphQLRequest
. So if we added them there, they would still need to be here also. And I actually think it's vary unlikely right now that you would want a different apq config per request.
Probably, you want the same apq config for all requests on the same NetworkTransport
. So I actually think the current setup is correct. RequestChainNetworkTransport
is initialized with an apqConfig
, and it passes that to each request if constructs. But having it here allows the interceptors to modify the APQ behavior of requests. I think that's what we want.
|
||
// MARK: - | ||
|
||
/// Describes the cache/networking behaviors that should be usedfor the execution of a GraphQL |
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.
/// Describes the cache/networking behaviors that should be usedfor the execution of a GraphQL | |
/// Describes the cache/networking behaviors that should be used for the execution of a GraphQL |
@@ -30,8 +32,8 @@ public protocol NetworkTransport: AnyObject, Sendable { | |||
public protocol SubscriptionNetworkTransport: NetworkTransport { | |||
|
|||
func send<Subscription: GraphQLSubscription>( | |||
subscription: Subscription, | |||
cachePolicy: CachePolicy | |||
subscription: Subscription, |
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.
subscription: Subscription, | |
subscription: Subscription, |
public let request: Request | ||
|
||
public init(request: Request) { | ||
self.request = request | ||
self.request = request |
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.
self.request = request | |
self.request = request |
} catch { | ||
#warning( | ||
""" | ||
TODO: If we are making cache miss return nil (instead of throwing error), then should |
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.
Does this reflect the thinking at the end of our conversation yesterday, or an evolution of that?
@@ -19,7 +19,7 @@ public final class RequestChainNetworkTransport: NetworkTransport, Sendable { | |||
/// | |||
/// Defaults to an empty dictionary. | |||
public let additionalHeaders: [String: String] | |||
|
|||
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.
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.
Not sure why there is whitespace being added in places like this?
This pull request introduces the new public facing APIs for the fetch methods of
ApolloClient
. A few other changes were made to enable these new APIs.Cache Policies
Depending on a combination of the
CachePolicy
and theOperationResponseFormat
,ApolloClient
fetch functions will either returnasync throws -> GraphQLResult<Query.Data>
orthrows -> AsyncThrowingStream<GraphQLResult<Query.Data>, any Error>
. In order to enable this, theCachePolicy`` now consists of multiple enums that can be used with different
ApolloClient` functions.All of the functions have the same calling signature (
fetch(query: cachePolicy: requestConfiguration:)
), with only differing return types. This allows the user to call the function passing any value for any of the nested cache policy enums and Swift will automatically infer the correct return type at the call site.NetworkTransport
&RequestChain
always return a stream of results, theApolloClient
functions know if they expect that stream to return multiple results or only a single result. For the single result cases, the client awaits the stream and just returns the first emitted value.This PR also introduces
FetchBehavior
. This is a newstruct
that encapsulates the behaviors described by any of the cache policies. For ease of use, theNetworkTransport
,RequestChain
, andGraphQLRequest
operate on theFetchBehavior
. The client converts the passed cache policy into aFetchBehavior
and passes it to theNetworkTransport
.Additionally a new
.networkElseCache
cache policy was introduced. While other cache policies have had their names changed and been restructured, no equivalent behavior previously existed.Request Configuration
This PR also introduces the
RequestConfiguration
struct. This encapsulates request-specific settings such asrequestTimeout
andwriteResultsToCache
. TheRequestConfiguration
is passed along to theNetworkTransport
, which is responsible for respecting the configuration values (typically by passing them to a constructedGraphQLRequest
instance).ApolloClient
is initialized with adefaultRequestConfiguration
, allowing therequestConfiguration
parameter on all fetch functions to be optional with a defaultnil
value. When no configuration is passed, thedefaultRequestConfiguration
is passed to theNetworkTransport
.RequestChain Behavior
The
RequestChain
previously would attempt a cache read (if required by theCachePolicy
) before anyGraphQLInterceptors
were called. Meaning for a.cacheOnly
request, the interceptors were never called at all. This PR changes that so thatGraphQLInterceptors
are called first, allowing them to mutate the request before the cache read. The cache response is now also passed back up through the interceptors prior to be emitted out of the result stream.RequestChain
was also modified to support the new.networkElseCache
cache policy.New Utility Extensions
This PR adds utility methods to
AsyncThrowingStream
for executing tasks and passing through results, improving asynchronous programming support.