Skip to content

Commit

Permalink
Merge pull request zino-hofmann#398 from micimize/client_defaults
Browse files Browse the repository at this point in the history
Client-level default policies
  • Loading branch information
micimize authored Aug 30, 2019
2 parents bef967a + fa24aab commit f0cdb0d
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 27 deletions.
46 changes: 31 additions & 15 deletions packages/graphql/lib/src/core/query_options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,25 +41,47 @@ enum ErrorPolicy {
all,
}

class Policies {
/// Specifies the [FetchPolicy] to be used.
FetchPolicy fetch;

/// Specifies the [ErrorPolicy] to be used.
ErrorPolicy error;
Policies({
this.fetch,
this.error,
});

Policies.safe(
this.fetch,
this.error,
) : assert(fetch != null, 'fetch policy must be specified'),
assert(error != null, 'error policy must be specified');

Policies withOverrides([Policies overrides]) => Policies.safe(
overrides?.fetch ?? fetch,
overrides?.error ?? error,
);
}

/// Base options.
class BaseOptions extends RawOperationData {
BaseOptions({
@required String document,
Map<String, dynamic> variables,
this.fetchPolicy,
this.errorPolicy,
this.policies,
this.context,
this.optimisticResult,
}) : super(document: document, variables: variables);

/// An optimistic result to eagerly add to the operation stream
Object optimisticResult;

/// Specifies the [FetchPolicy] to be used.
FetchPolicy fetchPolicy;
/// Specifies the [Policies] to be used during execution.
Policies policies;

/// Specifies the [ErrorPolicy] to be used.
ErrorPolicy errorPolicy;
FetchPolicy get fetchPolicy => policies.fetch;
ErrorPolicy get errorPolicy => policies.error;

/// Context to be passed to link execution chain.
Map<String, dynamic> context;
Expand All @@ -76,10 +98,9 @@ class QueryOptions extends BaseOptions {
this.pollInterval,
Map<String, dynamic> context,
}) : super(
policies: Policies(fetch: fetchPolicy, error: errorPolicy),
document: document,
variables: variables,
fetchPolicy: fetchPolicy,
errorPolicy: errorPolicy,
context: context,
optimisticResult: optimisticResult,
);
Expand All @@ -98,10 +119,9 @@ class MutationOptions extends BaseOptions {
ErrorPolicy errorPolicy = ErrorPolicy.none,
Map<String, dynamic> context,
}) : super(
policies: Policies(fetch: fetchPolicy, error: errorPolicy),
document: document,
variables: variables,
fetchPolicy: fetchPolicy,
errorPolicy: errorPolicy,
context: context,
);
}
Expand Down Expand Up @@ -148,11 +168,7 @@ class WatchQueryOptions extends QueryOptions {
return true;
}

if (a.fetchPolicy != b.fetchPolicy) {
return true;
}

if (a.errorPolicy != b.errorPolicy) {
if (a.policies != b.policies) {
return true;
}

Expand Down
63 changes: 63 additions & 0 deletions packages/graphql/lib/src/graphql_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,79 @@ import 'package:graphql/src/link/link.dart';
import 'package:graphql/src/link/operation.dart';
import 'package:meta/meta.dart';

/// The default [Policies] to set for each client action
class DefaultPolicies {
/// The default [Policies] for watchQuery.
/// Defaults to
/// ```
/// Policies(
/// FetchPolicy.cacheAndNetwork,
/// ErrorPolicy.none,
/// )
/// ```
Policies watchQuery;

/// The default [Policies] for query.
/// Defaults to
/// ```
/// Policies(
/// FetchPolicy.cacheFirst,
/// ErrorPolicy.none,
/// )
/// ```
Policies query;

/// The default [Policies] for mutate.
/// Defaults to
/// ```
/// Policies(
/// FetchPolicy.networkOnly,
/// ErrorPolicy.none,
/// )
/// ```
Policies mutate;
DefaultPolicies({
Policies watchQuery,
Policies query,
Policies mutate,
}) : this.watchQuery = _watchQueryDefaults.withOverrides(watchQuery),
this.query = _queryDefaults.withOverrides(query),
this.mutate = _mutateDefaults.withOverrides(mutate);

static final _watchQueryDefaults = Policies.safe(
FetchPolicy.cacheAndNetwork,
ErrorPolicy.none,
);

static final _queryDefaults = Policies.safe(
FetchPolicy.cacheFirst,
ErrorPolicy.none,
);
static final _mutateDefaults = Policies.safe(
FetchPolicy.networkOnly,
ErrorPolicy.none,
);
}

/// The link is a [Link] over which GraphQL documents will be resolved into a [FetchResult].
/// The cache is the initial [Cache] to use in the data store.
class GraphQLClient {
/// Constructs a [GraphQLClient] given a [Link] and a [Cache].
GraphQLClient({
@required this.link,
@required this.cache,
this.defaultPolicies,
}) {
defaultPolicies ??= DefaultPolicies();
queryManager = QueryManager(
link: link,
cache: cache,
);
}

/// The default [Policies] to set for each client action
DefaultPolicies defaultPolicies;

/// The [Link] over which GraphQL documents will be resolved into a [FetchResult].
final Link link;

Expand All @@ -35,18 +94,22 @@ class GraphQLClient {
/// This registers a query in the [QueryManager] and returns an [ObservableQuery]
/// based on the provided [WatchQueryOptions].
ObservableQuery watchQuery(WatchQueryOptions options) {
options.policies =
defaultPolicies.watchQuery.withOverrides(options.policies);
return queryManager.watchQuery(options);
}

/// This resolves a single query according to the [QueryOptions] specified and
/// returns a [Future] which resolves with the [QueryResult] or throws an [Exception].
Future<QueryResult> query(QueryOptions options) {
options.policies = defaultPolicies.query.withOverrides(options.policies);
return queryManager.query(options);
}

/// This resolves a single mutation according to the [MutationOptions] specified and
/// returns a [Future] which resolves with the [QueryResult] or throws an [Exception].
Future<QueryResult> mutate(MutationOptions options) {
options.policies = defaultPolicies.mutate.withOverrides(options.policies);
return queryManager.mutate(options);
}

Expand Down
20 changes: 8 additions & 12 deletions packages/graphql_flutter/lib/src/widgets/query.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,17 @@ class QueryState extends State<Query> {
ObservableQuery observableQuery;

WatchQueryOptions get _options {
FetchPolicy fetchPolicy = widget.options.fetchPolicy;

if (fetchPolicy == FetchPolicy.cacheFirst) {
fetchPolicy = FetchPolicy.cacheAndNetwork;
}
final QueryOptions options = widget.options;

return WatchQueryOptions(
document: widget.options.document,
variables: widget.options.variables,
fetchPolicy: fetchPolicy,
errorPolicy: widget.options.errorPolicy,
pollInterval: widget.options.pollInterval,
document: options.document,
variables: options.variables,
fetchPolicy: options.fetchPolicy,
errorPolicy: options.errorPolicy,
pollInterval: options.pollInterval,
fetchResults: true,
context: widget.options.context,
optimisticResult: widget.options.optimisticResult,
context: options.context,
optimisticResult: options.optimisticResult,
);
}

Expand Down

0 comments on commit f0cdb0d

Please sign in to comment.