sling_gql_link 1.0.1 copy "sling_gql_link: ^1.0.1" to clipboard
sling_gql_link: ^1.0.1 copied to clipboard

Run sling_gql's requests through a gql_link Link chain (auth, retries, persisted queries, websockets) as one Transport / SubscriptionTransport.

example/sling_gql_link_example.dart

// sling_gql over a gql_link chain: an auth link, a retry link and an
// HttpLink, as the client's one Transport.
//
// In a real app `Query` / `User` below are generated by `sling_gql_gen`
// (and `schema: slingSchema` replaces `rootFactory:`); they are written out
// here so the example stands on its own.
//
//   type Query { me: User! }
//   type User  { id: ID!  name: String! }

// ignore_for_file: avoid_print

import 'package:gql_http_link/gql_http_link.dart';
import 'package:gql_link/gql_link.dart';
import 'package:sling_gql/sling_gql.dart';
import 'package:sling_gql_link/sling_gql_link.dart';

Future<String> token() async => 'secret';

/// Adds `authorization` to the headers the client put in the context.
final authLink = Link.function(
  (request, [forward]) => Stream.fromFuture(token()).asyncExpand(
    (token) => forward!(
      request.updateContextEntry<HttpLinkHeaders>(
        (headers) => HttpLinkHeaders(
          headers: {...?headers?.headers, 'authorization': 'Bearer $token'},
        ),
      ),
    ),
  ),
);

/// Retries twice on a server error.
final retryLink = Link.function((request, [forward]) async* {
  for (var attempt = 1; ; attempt++) {
    try {
      await for (final response in forward!(request)) {
        yield response;
      }
      return;
    } on ServerException {
      if (attempt == 3) rethrow;
    }
  }
});

Future<void> main() async {
  const endpoint = 'https://api.example.com/graphql';
  final link = Link.from([authLink, retryLink, HttpLink(endpoint)]);

  final client = SlingClient<Query>(
    endpoint: Uri.parse(endpoint), // nominal: the HttpLink sends
    rootFactory: Query.root,
    headers: const {'x-app-version': '1.2.0'}, // reach the link's context
    transport: linkTransport(link),
    // With a websocket link routed by `Link.split`, subscriptions too:
    // subscriptionTransport: linkSubscriptionTransport(link),
  );

  try {
    print(await client.resolve((q) => q.me.name));
  } on SlingException catch (e) {
    print('${e.message} (${e.runtimeType})');
  } finally {
    client.dispose();
    await link.dispose();
  }
}

// --- What sling_gql_gen would generate ---------------------------------------

class Query extends Accessor {
  Query(super.recorder, super.selection, super.path);
  Query.root(Recorder r) : super(r, r.root, const []);

  User get me => object('me', User.new, keyed: true)!;
}

class User extends Accessor {
  User(super.recorder, super.selection, super.path);

  String? get id => scalar<String>('id');
  String? get name => scalar<String>('name');
}
0
likes
160
points
208
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Run sling_gql's requests through a gql_link Link chain (auth, retries, persisted queries, websockets) as one Transport / SubscriptionTransport.

Homepage
Repository (GitHub)
View/report issues

Topics

#graphql #gql-link #client

License

MIT (license)

Dependencies

flutter, gql, gql_exec, gql_http_link, gql_link, http, sling_gql

More

Packages that depend on sling_gql_link