MIT License PRs Welcome Watch on GitHub Star on GitHub Watch on GitHub Discord

A simple, powerful GraphQL Client for Flutter and Dart.

Documentation 📖

Features

  1. Fully Typed: work faster and safer with compile time checks and IDE autocomplete, including fully typed Cache reads and writes.
  2. 🔄 Built-In Code Generators: automatically generated immutable data classes for all your GraphQL Operations and Fragments, based on your schema.
  3. 🌐 Customizable Network Interface: highly customizable network interface using gql_link, allowing you to compose and extend Links.
  4. Normalized Optimistic Cache: keep data in sync with cache normalization and update your UI instantly with optimistic data.
  5. 💾 Multiple Data Stores: extensible Store interface with built-in MemoryStore and HiveStore (which uses hive for offline persistence).
  6. 📄 Refetch & Pagination: easily update responses with new data or combine multiple responses, allowing for seamless pagination.
  7. 📱 Flutter Widgets: Widgets for Queries, Mutations, and Subscriptions, available out of the box.

Getting Started

Check out the getting started section on the docs site.

Usage

Install Dependencies

Add the following to your pubspec.yaml:

dependencies:
  ferry:  #[latest-version]
  gql_http_link:  #[latest-version]

dev_dependencies:
  ferry_generator:  #[latest-version]
  build_runner:  #[latest-version]

Initialize the Client

This instantiates a client with the default configuration, including a Cache instance that uses a MemoryStore to store data.

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

final link = HttpLink("[path/to/endpoint]");

final client = Client(link: link);

Download Your GraphQL Schema

To generate our classes, we first need to downoad our GraphQL in SDL format to any location within the lib project directory. You can use the get-graphql-schema tool to download a schema from a GraphQL endpoint:

First, install the tool:

npm install -g get-graphql-schema

Next, download the schema:

get-graphql-schema ENDPOINT_URL > lib/schema.graphql

Create .graphql Files

We need to save all of our GraphQL operations to files that end with the .graphql extension.

The generated files are created as siblings to the .graphql file. To reduce clutter, we recommend placing your .graphql files in a /graphql subdirectory.

Build Generated Classes

Now that we've downloaded our GraphQL schema and saved our GraphQL Operations to .graphql files, we're almost ready to run the generator. The final step is to add a configuration file so that built_runner knows which generators to run and where to find our schema.

Add a build.yaml file to your project root with the following contents, replacing your_package_name and the path to your schema file accordingly.

targets:
  $default:
    builders:
      gql_build|schema_builder:
        enabled: true
      gql_build|ast_builder:
        enabled: true
      gql_build|data_builder:
        enabled: true
        options:
          schema: your_package_name|lib/schema.graphql
      gql_build|var_builder:
        enabled: true
        options:
          schema: your_package_name|lib/schema.graphql
      gql_build|serializer_builder:
        enabled: true
        options:
          schema: your_package_name|lib/schema.graphql

      ferry_generator|req_builder:
        enabled: true
        options:
          schema: your_package_name|lib/schema.graphql

Now you can build your dart generated files by calling:

pub run build_runner build

Or, if you are using flutter

flutter pub run build_runner build

Execute a Request

For example, let's say we've saved the following Reviews Query to a file named reviews.graphql:

query Reviews($first: Int, $offset: Int) {
  reviews(first: $first, offset: $offset) {
    id
    stars
    commentary
    createdAt
  }
}

Running the Ferry generator will create a reviews.req.gql.dart file with a Class named GReviewsReq. We can instantiate it like so:

final reviewsReq = GReviewsReq(
  (b) => b
    ..vars.first = 10
    ..vars.offset = 0,
);

Now, all we need to do is listen to the responseStream.

client.responseStream(reviewsReq).listen((response) => print(response));

Libraries

cache
ferry
plugins