Skip to content

Commit

Permalink
feat(graphql): re-add documentNode asdeprecated
Browse files Browse the repository at this point in the history
  • Loading branch information
micimize committed Jun 5, 2020
1 parent 9a5fff1 commit 20d0176
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 54 deletions.
136 changes: 136 additions & 0 deletions changelog-v3-v4.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# Migrating from v3 – v4

v4 aims to solve a number of sore spots, particularly with caching, largely by leveraging libraries from the https://github.com/gql-dart ecosystem. There has also been a concerted effort to add more API docstrings to the codebase.

## Cache overhaul
* There is now only a single `GraphQLCache`, which leverages [normalize](https://pub.dev/packages/normalize),
Giving us a much more `apollo`ish api including `typePolicies`
* `LazyCacheMap` has been deleted
* `GraphQLCache` marks itself for rebroadcasting (should fix some related issues)
* **`Store`** is now a seperate concern:

```dart
GraphQLCache(
// The default store is the InMemoryStore, which does NOT persist to disk
store: HiveStore(),
)
```

and persistence is broken into a seperate `Store` concern.

## We now use the [gql_link system](https://github.com/gql-dart/gql/tree/master/links/gql_link)
* Most links are re-exported from `graphql/client.dart`
* `QueryOptions`, `MutationOptions`, etc are turned into
[gql_exec](https://github.com/gql-dart/gql/tree/master/links/gql_exec) `Request`s
before being sent down the link chain.
* `documentNode` is deprecated in favor of `DocumentNode document` for consistency with `gql` libraries
* We won't leave alpha until we have [full backwards compatability](https://github.com/gql-dart/gql/issues/57)

```diff
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](https://pub.dev/packages/gql_dio_link), and all link-based clients benefit from new link development

## `subscription` API overhaul

`Subscription`/`client.subscribe` API is in line with the rest of the API

```dart
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) { /*...*/ },
);
```

## Minor changes

* As mentioned before, `documentNode: gql(...)` is now `document: gql(...)`.
* The exported `gql` utility adds `__typename` automatically.
**If you define your own, make sure to include `AddTypenameVisitor`,
or else that your cache `dataIdFromObject` works without it

### Enums are normalized and idiomatic

```diff
- QueryResultSource.OptimisticResult
+ QueryResultSource.optimisticResult
- QueryResultSource.Cache
+ QueryResultSource.cache
// etc

- QueryLifecycle.UNEXECUTED
+ QueryLifecycle.unexecuted
- QueryLifecycle.SIDE_EFFECTS_PENDING
+ QueryLifecycle.sideEffectsPending
```


### `client.fetchMore` (experimental)

The `fetchMore` logic is now available for when one isn't using `watchQuery`:
```dart
/// 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,
options: options,
previousResult: latestResult,
);
_latestResult = result;
return result;
}
}
```
1 change: 0 additions & 1 deletion examples/starwars/lib/client_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ ValueNotifier<GraphQLClient> clientFor({
);

link = Link.split((request) => request.isSubscription, websocketLink, link);
;
}

return ValueNotifier<GraphQLClient>(
Expand Down
11 changes: 7 additions & 4 deletions packages/graphql/lib/src/core/mutation_options.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// ignore_for_file: deprecated_member_use_from_same_package
import 'package:graphql/src/cache/cache.dart';
import 'package:graphql/src/core/_base_options.dart';
import 'package:graphql/src/core/observable_query.dart';
import 'package:meta/meta.dart';

import 'package:gql/ast.dart';
import 'package:gql_exec/gql_exec.dart';
Expand All @@ -20,7 +20,9 @@ typedef OnError = void Function(OperationException error);

class MutationOptions extends BaseOptions {
MutationOptions({
@required DocumentNode document,
DocumentNode document,
@Deprecated('Use `document` instead. Will be removed in 5.0.0')
DocumentNode documentNode,
String operationName,
Map<String, dynamic> variables = const {},
FetchPolicy fetchPolicy,
Expand All @@ -30,10 +32,11 @@ class MutationOptions extends BaseOptions {
this.onCompleted,
this.update,
this.onError,
}) : super(
}) : assert(document ?? documentNode != null, 'document must not be null'),
super(
fetchPolicy: fetchPolicy,
errorPolicy: errorPolicy,
document: document,
document: document ?? documentNode,
operationName: operationName,
variables: variables,
context: context,
Expand Down
2 changes: 1 addition & 1 deletion packages/graphql/lib/src/core/observable_query.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ enum QueryLifecycle {
/// Polling for results periodically
polling,

/// [Observab]
/// Was polling but [ObservableQuery.stopPolling()] was called
pollingStopped,

/// Results are being fetched, and will trigger
Expand Down
25 changes: 18 additions & 7 deletions packages/graphql/lib/src/core/query_options.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// ignore_for_file: deprecated_member_use_from_same_package
import 'package:graphql/src/core/_base_options.dart';
import 'package:meta/meta.dart';

Expand All @@ -10,18 +11,21 @@ import 'package:graphql/src/core/policies.dart';
/// Query options.
class QueryOptions extends BaseOptions {
QueryOptions({
@required DocumentNode document,
DocumentNode document,
@Deprecated('Use `document` instead. Will be removed in 5.0.0')
DocumentNode documentNode,
String operationName,
Map<String, dynamic> variables = const {},
FetchPolicy fetchPolicy,
ErrorPolicy errorPolicy,
Object optimisticResult,
this.pollInterval,
Context context,
}) : super(
}) : assert(document ?? documentNode != null, 'document must not be null'),
super(
fetchPolicy: fetchPolicy,
errorPolicy: errorPolicy,
document: document,
document: document ?? documentNode,
operationName: operationName,
variables: variables,
context: context,
Expand Down Expand Up @@ -74,6 +78,8 @@ class SubscriptionOptions extends BaseOptions {
class WatchQueryOptions extends QueryOptions {
WatchQueryOptions({
@required DocumentNode document,
@Deprecated('Use `document` instead. Will be removed in 5.0.0')
DocumentNode documentNode,
String operationName,
Map<String, dynamic> variables = const {},
FetchPolicy fetchPolicy,
Expand All @@ -83,9 +89,10 @@ class WatchQueryOptions extends QueryOptions {
this.fetchResults = false,
bool eagerlyFetchResults,
Context context,
}) : eagerlyFetchResults = eagerlyFetchResults ?? fetchResults,
}) : assert(document ?? documentNode != null, 'document must not be null'),
eagerlyFetchResults = eagerlyFetchResults ?? fetchResults,
super(
document: document,
document: document ?? documentNode,
operationName: operationName,
variables: variables,
fetchPolicy: fetchPolicy,
Expand Down Expand Up @@ -123,10 +130,14 @@ class WatchQueryOptions extends QueryOptions {
/// options for fetchMore operations
class FetchMoreOptions {
FetchMoreOptions({
this.document,
DocumentNode document,
@Deprecated('Use `document` instead. Will be removed in 5.0.0')
DocumentNode documentNode,
this.variables = const {},
@required this.updateQuery,
}) : assert(updateQuery != null);
}) : assert(updateQuery != null),
assert(document ?? documentNode != null, 'document must not be null'),
this.document = document ?? documentNode;

DocumentNode document;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ class GraphQLWidgetScreen extends StatelessWidget {
if (ENABLE_WEBSOCKETS) {
final websocketLink = WebSocketLink('ws://localhost:8080/ws/graphql');

link = link.concat(websocketLink);
link = Link.split(
(request) => request.isSubscription,
websocketLink,
link,
);
}

final client = ValueNotifier<GraphQLClient>(
Expand Down
40 changes: 0 additions & 40 deletions v4_devnotes.md

This file was deleted.

0 comments on commit 20d0176

Please sign in to comment.