Developer

GraphQL Networking

Make sure to read the documentation for eit_networking, as this package reuses its entire functionality.

Main purpose of this package is to abstract the configuration needed for using GraphQL. Selected package is graphql. There are three types of operations in GraphQL - Queries, Mutations and Subscriptions. Queries and Mutations are always served over HTTP. Subscription, in most cases, uses websockets, but other implementaitons are possibly.

For HTTP communication we use dio client, configured via eit_networking interfaces. To work with dio and graphql, we need a Link. Links are similar to interceptors in Dio. We have a custom implementation of DioLink, which is heavily inspired by gql_dio_link.

For websocket communication we use standard WebSocketLink from graphql.


Installation

dart pub add eit_networking_gql  --hosted-url=https://gitea.whitelabel.mobile.embedit.dev/api/packages/platform/pub/

!IMPORTANT You need access token for fetching from private pub repository. ELI add token automatically

Usage

Before you will run first http request you must init GqlApiClient.

await GqlApiClient.initialize(config, store: store);

Configuration

Default configuration set from eit_networking

AttributeDefault valueDescription
baseUrlnone requiredBase url of your api server
connectionTimeout5s
receiveTimeout15s
useIsolatefalsejsonDecode in isolate
useNativetrueUse native if possible
debugfalselog to console
validateStatuses200, 201, 203, 205, 302status codes as validation
useConnectivitytrueNetwork change listener
checkInterval5speriodic check connectivity
interceptorsemptydio client interceptors

Default configuration set for additional graphql parameters

AttributeDefault valueDescription
graphQlEndpointUrlnone requiredURL of the graphql endpoint, usually '/graphql'
baseLinknoneIf present, will be connected to created link with baseLink.concat(link)
websocketUrlnoneIf present, the client will be configured to use Websockets for subscriptions

Store

Cache store is a required parameter of the GraphQL client. Two main implementations are InMemoryCacheStore and HiveStore. For HiveStore, check eit_storage and its Boxes. There is also an implementation of AlwaysEmptyStore, in case you want to forcefully disable the cache on the store level.

Simple configuration of the client may look like this:

    final box = getEitBox(); // use your own implementation

    final config = const GqlApiConfig(
        'http://127.0.0.1:3000',
        'graphql',
        websocketUrl: 'ws://localhost:3000',
      );

    final store = HiveStore(box);
    
    final gqlApiClient = await GqlApiClient.initialize(config, store: store);

Api request

Extensions

Used extensions are same as with eit_networking.

FutureResponse.request

  // original
  final result = await waitTask();
  result.tryResult(onFailure, onSuccess)

  // shorthand
  final result = await waitTask().request(converter);

FutureResponse.run - equivalent to

/// original
waitTask().then((result)=> result.tryResult(onFailure, onSuccess));

/// shorthand
waitTask().run(onFailure, onSuccess);

Api query

Standard call on GraphQLClient with generated extensions

returns standard response with DTO or throw exception, so you have to use try/catch

final GraphQLClient apiClient = gqlApiClient.gql; // we initialised the gqlApiClient above

try{
    // this is a real code example of getting detail by id
    final result = apiClient
        .query$ReadCharacterDetail(
          Options$Query$ReadCharacterDetail(
            variables: Variables$Query$ReadCharacterDetail(id: id),
          ),
        );
} catch (e, s){
    logger.e(e, s);
    rethrow;
}

Use request shorthand to convert Dto to Entity and error handler

return Future<Result<ApiFailure, MyEntity>>

final GraphQLClient apiClient = gqlApiClient.gql; // we initialised the gqlApiClient above

final result = apiClient
        .query$ReadCharacterDetail( // generated extension method
          Options$Query$ReadCharacterDetail( // generated class
            variables: Variables$Query$ReadCharacterDetail(id: id), // generated class
          ),
        )
        .request((data) => MyEntity(data)); // use custom mapper from generated response (data is typed)

result.tryResult(onSuccess:(data){
    ...
}, onFailure: (exception){
    ...
})

Api Failure

There are two more exceptions added on top of ApiFailure from eit_networking. GraphQlErrorsException, which gets fired when the response contains errors (all the errors are part of the exception data for further processing) and GraphQlLinkParserException, which gets fired when the DioLink could not parse the query or response.

How to use in Bloc

The interface of repositories remains the same as in eit_networking.

/// Simple result mapper
on<FetchEvent>((event, emit){
    repository.get(event.id).request<MyEntity>(MyEntityX.fromDto).run(
        onSuccess: SuccessState.new,
        onFailure: FailureState.new,
    );
})

Copyright © 2025. All rights reserved.