Skip to content

Initialize GraphQL Client

Problem

You need to initialize the GraphQL client with proper configuration, middleware (TypedLinks), cache handlers, and authentication token management.

The GraphQL client uses a builder pattern with TypedLinks middleware for request processing:

@Riverpod(keepAlive: true)
GqlClient gqlClient(Ref ref) {
final cacheHandler = ref.read(cacheHandlerProvider);
GqlClientBuilder.addTypedLink(
PriorityTypedLink(processingDelay: const Duration(milliseconds: 500)),
);
GqlClientBuilder.init(
options: GqlClientOptions(
httpEndpoint:
'${const String.fromEnvironment('BASE_URL')}/graphqllayer/GraphQLMutation/Mutation',
keepAlive: const Duration(seconds: 60),
updateCacheHandlers: cacheHandler.handlers,
),
);
final client = GqlClientBuilder.getInstance();
return client;
}

TypedLinks are middleware that process requests before they reach the terminating HTTP link:

GqlClientBuilder.addTypedLink(
PriorityTypedLink(processingDelay: const Duration(milliseconds: 500)),
);
class AuthTypedLink extends TypedLink {
@override
Stream<OperationResponse<TData, TVars>> request<TData, TVars>(
OperationRequest<TData, TVars> request,
NextTypedLink forward,
) {
final token = AuthService.instance.currentToken;
final modifiedRequest = request.rebuild((b) => b
..context = request.context.rebuild((cb) => cb
..entry<HttpLinkHeaders>(HttpLinkHeaders.key)?.headers.addAll({
'Authorization': 'Bearer $token',
}) ?? cb.entry(HttpLinkHeaders.key, HttpLinkHeaders(headers: {
'Authorization': 'Bearer $token',
}))
)
);
return forward(modifiedRequest);
}
}
class LoggingTypedLink extends TypedLink {
@override
Stream<OperationResponse<TData, TVars>> request<TData, TVars>(
OperationRequest<TData, TVars> request,
NextTypedLink forward,
) {
print('🚀 GraphQL Request: ${request.operation.operationName}');
return forward(request).map((response) {
if (response.hasErrors) {
print('❌ GraphQL Error: ${response.graphqlErrors}');
} else {
print('✅ GraphQL Success: ${request.operation.operationName}');
}
return response;
});
}
}
GqlClientOptions(
httpEndpoint: 'https://api.example.com/graphql',
keepAlive: const Duration(seconds: 60),
updateCacheHandlers: cacheHandler.handlers,
defaultHeaders: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
connectTimeout: const Duration(seconds: 30),
receiveTimeout: const Duration(seconds: 30),
)
const baseUrl = String.fromEnvironment('BASE_URL', defaultValue: 'http://localhost:3000');
const graphqlEndpoint = '$baseUrl/graphqllayer/GraphQLMutation/Mutation';
void updateAuthToken(String token) {
GqlClientBuilder.updateToken(token);
}
class AuthService {
void onTokenRefresh(String newToken) {
GqlClientBuilder.updateToken(newToken);
}
void onLogout() {
GqlClientBuilder.updateToken('');
}
}

TypedLinks are processed in the order they’re added:

GqlClientBuilder.addTypedLink(LoggingTypedLink());
GqlClientBuilder.addTypedLink(AuthTypedLink());
GqlClientBuilder.addTypedLink(PriorityTypedLink(processingDelay: const Duration(milliseconds: 500)));

Processing Order:

  1. LoggingTypedLink - Logs requests and responses
  2. AuthTypedLink - Adds authentication headers
  3. PriorityTypedLink - Handles request prioritization
  4. HttpLink - Terminating link that makes HTTP requests
  1. Middleware Chain - TypedLinks provide flexible request/response processing
  2. Authentication - Easy token management with updateToken()
  3. Caching - Integrated cache handler support
  4. Priority Handling - Built-in request prioritization
  5. Environment Config - Flexible endpoint configuration
  6. Singleton Pattern - Single client instance across the app