Henrique Melo
Henrique Melo

Reputation: 105

Add headers to request using Ferry with Flutter

it's my first time using Ferry to make GraphQL requests. My GraphQL Server has some queries that need an HTTP header for authorization.

I need to be able to add the header after initializing the client.

client.dart:

Future<Client> initClient() async {
  await Hive.initFlutter();

  final box = await Hive.openBox<Map<String, dynamic>>("graphql");

  await box.clear();

  final store = HiveStore(box);

  final cache = Cache(store: store);

  final link = HttpLink("example.com/");

  final client = Client(
    link: link,
    cache: cache,
  );

  return client;
}

main.dart:

void main() async{
  final client = await initClient();
  GetIt.I.registerLazySingleton<Client>(() => client);
  runApp(MyApp());
}

request file:

    client.request(Req).listen((response) {
      print(response.graphqlErrors); // It will return an error because theres no header with the token
      print(response.data);
    });

Upvotes: 4

Views: 2807

Answers (3)

Mauro Aguilar
Mauro Aguilar

Reputation: 1338

Alternatively, one can send custom headers per request by adding a HttpLinkHeaders entry to the request Context.

Here's a quick example:

  1. Init your client with HttpLink:
Future<Client> initClient(Config config) async {
  await Hive.initFlutter();
  final box = await Hive.openBox<dynamic>('graphql');
  final store = HiveStore(box);
  final cache = Cache(store: store);
  final link = HttpLink(config.graphqlServerUrl);
  return Client(link: link, cache: cache);
}
  1. Setup custom Context builder utility:
import 'package:gql_exec/gql_exec.dart'; // requires this package

Context buildContextWithHttpHeaders(Map<String, String> headers) {
  return const Context().withEntry(HttpLinkHeaders(headers: headers));
}
  1. Build the custom context with your headers and provide it to your request builders:
final token = await getAuthToken();
final headers = { 'Authorization': 'Bearer $token' };
final request = GSomeReq(
    (builder) => builder
      ..fetchPolicy = FetchPolicy.NetworkOnly
      ..context = buildContextWithHttpHeaders(headers),
);

Dependencies in this example:

ferry: ^0.16.0+1
gql_exec: ^1.0.0+1
gql_http_link: ^1.1.0

HttpLink will internally retrieve headers through the request context before executing it:

// gql_http_link: ^1.1.0
Map<String, String> _getHttpLinkHeaders(Request request) {
  ...
  final HttpLinkHeaders? linkHeaders = request.context.entry();
  ...
}

http.BaseRequest _prepareRequest(Request request) {
  ...
  final contextHeaders = _getHttpLinkHeaders(request);
  final headers = {
    "Content-type": "application/json",
    "Accept": "*/*",
    ...defaultHeaders,
    ...contextHeaders,
  };
  ...
}

Upvotes: 0

Tun Cham Roeun
Tun Cham Roeun

Reputation: 164

Try this implementation work for me!

save auth_link.dar from graphql_flutter

Working example

import 'dart:async';

import 'package:ferry/ferry.dart';
import 'package:ferry_hive_store/ferry_hive_store.dart';
import 'package:gql_http_link/gql_http_link.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'path_to/auth_link.dart';
Future<Client> initClient() async {
  final box = await Hive.openBox("graphql");
  await box.clear();
  final store = HiveStore(box);
  final cache = Cache(store: store);
  var httpLink = HttpLink('http://localhost:4000/graphql');
  final AuthLink authLink = AuthLink(
    getToken: () async => await getBoxToken(),
  );

  final Link link = authLink.concat(httpLink);
  final client = Client(
    link: link,
    cache: cache,
  );
  return client;
}

FutureOr<String> getBoxToken() async {
  final box = await Hive.openBox("fireToken");
  return 'Bearer ${box.get('token')}';
}

Upvotes: 3

Matthew Rideout
Matthew Rideout

Reputation: 8518

Here is a simple example for adding headers to the Ferry GraphQL client requests. In this example, we add an Authorization Bearer Token to the request.

The headers are added by adding an object to the defaultHeaders parameter on creation of the HttpLink object.

graphql_service.dart

import 'package:ferry/ferry.dart';
import 'package:gql_http_link/gql_http_link.dart';

Client initGqlClient(String url) {
  final link = HttpLink(
    url,
    defaultHeaders: {
      'Authorization':
          'Bearer eyJ0eXAiOi...',
    },
  );

  final client = Client(link: link);

  return client;
}

Upvotes: 8

Related Questions