Using the graphql_flutter Package to Integrate GraphQL into Your Flutter App

GraphQL has emerged as a powerful alternative to REST APIs, offering a more efficient and flexible way to fetch and manipulate data. For Flutter developers, integrating GraphQL into your apps can significantly enhance data fetching capabilities and improve overall performance. The graphql_flutter package provides a robust and straightforward way to integrate GraphQL into Flutter applications. This blog post will guide you through using the graphql_flutter package to seamlessly integrate GraphQL into your Flutter app.

What is GraphQL?

GraphQL is a query language for your API and a server-side runtime for executing those queries. Unlike REST, which fetches a fixed set of data for each endpoint, GraphQL allows clients to request specific data, resulting in more efficient data transfer and reduced over-fetching. Key benefits of GraphQL include:

  • Efficient Data Fetching: Clients request only the data they need.
  • Reduced Over-Fetching: No unnecessary data is transferred.
  • Strongly Typed Schema: Ensures type safety and helps with debugging.
  • Introspection: Allows clients to explore the API’s capabilities.

Why Use graphql_flutter in Flutter?

The graphql_flutter package is designed to simplify the integration of GraphQL APIs into Flutter applications. It offers several advantages:

  • Easy Integration: Simple setup and intuitive API for GraphQL operations.
  • Caching Support: Built-in caching to improve performance and reduce network requests.
  • UI Components: Pre-built widgets for displaying data and handling loading/error states.
  • Subscription Support: Real-time data updates with GraphQL subscriptions.

How to Integrate GraphQL into Your Flutter App Using graphql_flutter

To start integrating GraphQL into your Flutter app, follow these steps:

Step 1: Add the graphql_flutter Dependency

First, add the graphql_flutter package to your pubspec.yaml file:

dependencies:
  flutter:
    sdk: flutter
  graphql_flutter: ^5.1.2 

Run flutter pub get in your terminal to install the package.

Step 2: Set Up the GraphQL Client

Initialize the GraphQL client with the endpoint URL and necessary configurations. Create a file named graphql_client.dart:

import 'package:flutter/material.dart';
import 'package:graphql_flutter/graphql_flutter.dart';

final HttpLink httpLink = HttpLink(
  'https://rickandmortyapi.graphcdn.app/', // Replace with your GraphQL endpoint
);

ValueNotifier<GraphQLClient> client = ValueNotifier(
  GraphQLClient(
    link: httpLink,
    cache: GraphQLCache(store: HiveStore()),
  ),
);

class GraphQLProvider extends StatelessWidget {
  GraphQLProvider({required this.child});

  final Widget child;

  @override
  Widget build(BuildContext context) {
    return GraphQLProvider(client: client, child: child);
  }
}

In this code:

  • HttpLink defines the GraphQL endpoint.
  • GraphQLCache configures caching using HiveStore.
  • GraphQLClient creates a client instance with the specified link and cache.
  • The GraphQLProvider wraps your app to make the GraphQL client available throughout your widget tree.

Step 3: Wrap Your App with GraphQLProvider

Wrap your main app widget with the GraphQLProvider in main.dart:

import 'package:flutter/material.dart';
import 'graphql_client.dart';
import 'home_page.dart'; // Create this file in Step 4

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'GraphQL Flutter App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: GraphQLProvider(child: HomePage()),
    );
  }
}

Step 4: Create a Widget to Query Data

Create a new file named home_page.dart to fetch and display data using GraphQL queries:

import 'package:flutter/material.dart';
import 'package:graphql_flutter/graphql_flutter.dart';

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final String query = """
      query GetCharacters {
        characters {
          results {
            id
            name
          }
        }
      }
    """;

    return Scaffold(
      appBar: AppBar(
        title: Text('GraphQL Characters'),
      ),
      body: Query(
        options: QueryOptions(
          document: gql(query),
        ),
        builder: (QueryResult result, {Refetch? refetch, FetchMore? fetchMore}) {
          if (result.hasException) {
            return Center(child: Text("Error: ${result.exception.toString()}"));
          }

          if (result.isLoading) {
            return Center(child: CircularProgressIndicator());
          }

          List? characters = result.data?['characters']['results'];

          if (characters == null) {
            return Center(child: Text('No data available'));
          }

          return ListView.builder(
            itemCount: characters.length,
            itemBuilder: (context, index) {
              final character = characters[index];
              return ListTile(
                leading: CircleAvatar(
                  child: Text(character['id'].toString()),
                ),
                title: Text(character['name']),
              );
            },
          );
        },
      ),
    );
  }
}

In this code:

  • The Query widget executes the GraphQL query.
  • The builder function handles different states: loading, error, and data.
  • The data is extracted and displayed in a ListView.

Step 5: Run Your Flutter App

Run your Flutter app using flutter run. You should see a list of characters fetched from the GraphQL API.
Make sure that you have an active internet connection.

Advanced Usage

Caching

The graphql_flutter package includes a sophisticated caching mechanism that can significantly improve performance. By default, the cache is stored in memory. For persistent storage, use HiveStore as shown earlier.

Mutations

Mutations are used to modify data on the server. Use the Mutation widget in a similar way to the Query widget:

import 'package:flutter/material.dart';
import 'package:graphql_flutter/graphql_flutter.dart';

class AddTodoMutation extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final String mutation = """
      mutation AddTodo(\$title: String!, \$completed: Boolean!) {
        addTodo(title: \$title, completed: \$completed) {
          id
          title
          completed
        }
      }
    """;

    return Mutation(
      options: MutationOptions(
        document: gql(mutation),
        onCompleted: (dynamic result) {
          print("Mutation completed: $result");
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(content: Text('Todo Added!')),
          );
        },
      ),
      builder: (RunMutation runMutation, QueryResult<Object?>? result) {
        return ElevatedButton(
          onPressed: () {
            runMutation({
              'title': 'My New Todo',
              'completed': false,
            });
          },
          child: Text('Add Todo'),
        );
      },
    );
  }
}

Subscriptions

For real-time data updates, use GraphQL subscriptions. Implement a Subscription widget similar to Query and Mutation.

Conclusion

Integrating GraphQL into your Flutter app using the graphql_flutter package is a straightforward and efficient way to manage data fetching and manipulation. By following the steps outlined in this guide, you can set up a GraphQL client, perform queries, execute mutations, and implement subscriptions, resulting in a more responsive and efficient Flutter application. The package’s robust features, including caching and UI components, make it an excellent choice for modern Flutter development.

Leave a Reply

Your email address will not be published. Required fields are marked *