v4 aims to solve a number of sore spots, particularly with caching, largely by leveraging libraries from the gql-dart ecosystem.
There has also been an effort to add more API docs and docs in general, particularly in the graphql
README.
NB Note that if you are depending on
PersistedQueriesLink
, its migration is not yet complete
- There is now only a single
GraphQLCache
, which leverages normalize, Giving us a much moreapollo
ish API.typePolicies
- direct cache access via
readQuery
,writeQuery
,readFragment
, andwriteFragment
/// see more in graphql's readme client.writeQuery(myQueryOptions.asRequest, queryData); client.readQuery(myQueryOptions.asRequest);
LazyCacheMap
has been deletedGraphQLCache
marks itself for rebroadcasting (should fix some related issues)Store
now decouples persistence from the cache:
/// Only necessary on flutter
void main() async {
await initHiveForFlutter();
runApp(MyApp());
}
GraphQLCache(
// The default store is the InMemoryStore, which does NOT persist to disk
store: GraphQLCache(store: HiveStore()),
)
We now use the gql_link system
- Most links are re-exported from
graphql/client.dart
QueryOptions
,MutationOptions
, etc are turned into gql_execRequest
s before being sent down the link chain.documentNode
is deprecated in favor ofDocumentNode document
for consistency withgql
libraries
final httpLink = HttpLink(
- uri: 'https://api.github.com/graphql',
+ 'https://api.github.com/graphql',
);
final authLink = AuthLink(
getToken: () async => 'Bearer $YOUR_PERSONAL_ACCESS_TOKEN',
);
var link = authLink.concat(httpLink);
if (ENABLE_WEBSOCKETS) {
final websocketLink = WebSocketLink(
- uri: 'ws://localhost:8080/ws/graphql'
+ 'ws://localhost:8080/ws/graphql'
);
- link = link.concat(websocketLink);
+ // split request based on type
+ link = Link.split(
+ (request) => request.isSubscription,
+ websocketLink,
+ link,
+ );
}
This makes all link development coordinated across the ecosystem, so that we can leverage existing links like gql_dio_link, and all link-based clients benefit from new link development
Subscription
/client.subscribe
API is in line with the rest of the API
final subscriptionDocument = gql(
r'''
subscription reviewAdded {
reviewAdded {
stars, commentary, episode
}
}
''',
);
// graphql/client.dart usage
subscription = client.subscribe(
SubscriptionOptions(
document: subscriptionDocument
),
);
// graphql_flutter/graphql_flutter.dart usage
Subscription(
options: SubscriptionOptions(
document: subscriptionDocument,
),
builder: (result) { /*...*/ },
);
pollInterval
, which used to be anint
ofseconds
, is now aDuration
- As mentioned before,
documentNode: gql(...)
is nowdocument: gql(...)
. - The exported
gql
utility adds__typename
automatically. **If you define your own, make sure to includeAddTypenameVisitor
, or else that your cachedataIdFromObject
works without it
- QueryResultSource.OptimisticResult
+ QueryResultSource.optimisticResult
- QueryResultSource.Cache
+ QueryResultSource.cache
// etc
- QueryLifecycle.UNEXECUTED
+ QueryLifecycle.unexecuted
- QueryLifecycle.SIDE_EFFECTS_PENDING
+ QueryLifecycle.sideEffectsPending
The fetchMore
logic is now available for when one isn't using watchQuery
:
/// Untested example code
class MyQuery {
QueryResult latestResult;
QueryOptions initialOptions;
FetchMoreOptions get _fetchMoreOptions {
// resolve the fetchMore params based on some data in lastestResult,
// like last item id or page number, and provide custom updateQuery logic
}
Future<QueryResult> fetchMore() async {
final result = await client.fetchMore(
_fetchMoreOptions,
originalOptions: options,
previousResult: latestResult,
);
latestResult = result;
return result;
}
}