Skip to content
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

Need more headers in AuthLink #173

Closed
endigo opened this issue Feb 17, 2019 · 7 comments
Closed

Need more headers in AuthLink #173

endigo opened this issue Feb 17, 2019 · 7 comments
Assignees
Labels
next Feature or report is related to next question Further information is requested
Milestone

Comments

@endigo
Copy link

endigo commented Feb 17, 2019

Our API service uses access-token and refresh token.

Here just one header: 'Authorization'
/~https://github.com/zino-app/graphql-flutter/blob/next/lib/src/link/auth/link_auth.dart#L21

We need 3 custom named headers.
for example:

HttpLink(uri: global.graphqlEndpoint, headers: {
  'x-token': state.user.accessToken,
  'x-refresh-token': state.user.refreshToken,
  'accept-language': locale.toString()
}),

Thanks.

@HofmannZ HofmannZ added question Further information is requested next Feature or report is related to next labels Feb 17, 2019
@HofmannZ HofmannZ self-assigned this Feb 17, 2019
@HofmannZ HofmannZ added this to the 1.0.0 milestone Feb 17, 2019
@HofmannZ
Copy link
Member

You can write your own Link:

typedef GetHeaders = Future<Map<String, String>> Function();

class CustomAuthLink extends Link {
  CustomAuthLink({
    this.getHeaders,
  }) : super(
          request: (Operation operation, [NextLink forward]) {
            StreamController<FetchResult> controller;

            Future<void> onListen() async {
              try {
                final Map<String, String> headers = await getHeaders();

                operation.setContext(<String, Map<String, String>>{
                  'headers': headers
                });
              } catch (error) {
                controller.addError(error);
              }

              await controller.addStream(forward(operation));
              await controller.close();
            }

            controller = StreamController<FetchResult>(onListen: onListen);

            return controller.stream;
          },
        );

  GetHeaders getHeaders;
}

And then you can implement it just as you would with the AuthLink.

Hope that helps!

@HofmannZ
Copy link
Member

Closing, seems revolved.

@5hanth
Copy link

5hanth commented Feb 2, 2021

@HofmannZ need to reopen this as the above CustomAuthLink's parameter signatures fails for 4.0.0

@HofmannZ
Copy link
Member

HofmannZ commented Feb 2, 2021

@5hanth we moved to a new link system, see /~https://github.com/zino-app/graphql-flutter/blob/beta/changelog-v3-v4.md#we-now-use-the-gql_link-system

@bgparkerdev
Copy link

If people are having a hard time finding an example. /~https://github.com/gql-dart/gql/blob/master/links/gql_link/example/gql_link_example.dart

@MSRPRO
Copy link

MSRPRO commented Oct 5, 2021

You can create your own link (updated answer 2021) :

import 'dart:async';

import 'package:graphql/client.dart';

typedef _RequestTransformer = FutureOr<Request> Function(Request request);

class CustomAuthLink extends _AsyncReqTransformLink {
  CustomAuthLink({
    required this.getHeaders,
  }) : super(requestTransformer: transform(getHeaders));

  final FutureOr<Map<String, String>>? Function() getHeaders;

  static _RequestTransformer transform(
    FutureOr<Map<String, String>>? Function() getHeaders,
  ) =>
      (Request request) async {
        final Map<String, String>? headers = await getHeaders();
        return request.updateContextEntry<HttpLinkHeaders>(
          (_headers) => HttpLinkHeaders(
            headers: headers!,
          ),
        );
      };
}

class _AsyncReqTransformLink extends Link {
  final _RequestTransformer requestTransformer;

  _AsyncReqTransformLink({
    required this.requestTransformer,
  });

  @override
  Stream<Response> request(
    Request request, [
    NextLink? forward,
  ]) async* {
    final req = await requestTransformer(request);

    yield* forward!(req);
  }
}

@SamerOrfali22
Copy link

SamerOrfali22 commented Oct 16, 2024

I think the previous solutions are expired and the new link system and the example is not simple to understand and use, so
here is my the straight forward solution when you have dynamic headers for each request
in my case I need to send the current language for example with each request

so first I have singleton service has one instance of the client with the default headers

 class GraphqlService {
  final GraphQLClient _client;

  GraphqlService._(this._client);

  static GraphqlService? _instance;

  static Future<GraphqlService> instance() async {
    if (_instance != null) {
      return _instance!;
    }
    final HttpLink httpLink = HttpLink(
      AppConfig.graphqlUrl,
      defaultHeaders: CommonHttp.defaultHeaders,
      useGETForQueries: false,
    );

    final graphQlClient = GraphQLClient(
      cache: GraphQLCache(),
      link: httpLink,
    );

    _instance = GraphqlService._(graphQlClient);
    return _instance!;
  }

  Future<QueryResult> query(QueryOptions options) async {
    return await _client.query(options);
  }

  Future<QueryResult> mutate(MutationOptions options) async {
    return await _client.mutate(options);
  }
}

and using the query like this

  final client = await GraphqlService.instance();
      final dynamicHeaders = await CommonHttp.getDynamicHeaders();

      final result = await client.query(
        QueryOptions(
          document: gql(query),
          variables: variables,
          context: Context.fromList([
            HttpLinkHeaders(headers: dynamicHeaders),
          ]),
        ),
      );

so the dynamic headers will be added to the default headers in each request

also you can add RequestExtensionsThunk,HttpLinkResponseContext,ResponseExtensions to this list.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
next Feature or report is related to next question Further information is requested
Projects
None yet
Development

No branches or pull requests

6 participants