Working with GraphQL APIs in Flutter
Aug 25, 2025



Summary
Summary
Summary
Summary
Learn to integrate GraphQL in Flutter mobile development using graphql_flutter. This tutorial covers client setup, Dart models for schemas, writing queries and mutations, handling responses with caching policies, and integrating data into widgets for a responsive UI.
Learn to integrate GraphQL in Flutter mobile development using graphql_flutter. This tutorial covers client setup, Dart models for schemas, writing queries and mutations, handling responses with caching policies, and integrating data into widgets for a responsive UI.
Learn to integrate GraphQL in Flutter mobile development using graphql_flutter. This tutorial covers client setup, Dart models for schemas, writing queries and mutations, handling responses with caching policies, and integrating data into widgets for a responsive UI.
Learn to integrate GraphQL in Flutter mobile development using graphql_flutter. This tutorial covers client setup, Dart models for schemas, writing queries and mutations, handling responses with caching policies, and integrating data into widgets for a responsive UI.
Key insights:
Key insights:
Key insights:
Key insights:
Setting Up the GraphQL Client: Initialize GraphQLClient with HttpLink and in-memory cache for efficient API calls.
Defining Schemas and Models: Map server types to Dart classes using json_serializable for type-safe parsing.
Writing Queries and Mutations: Use gql tags to define precise operations, selecting only required fields.
Handling Responses and Caching: Manage loading, errors, and caching strategies with fetchPolicy and QueryResult.
Integrating with Widgets: Leverage Query and Mutation builders for reactive UI updates based on GraphQL data.
Introduction
GraphQL has become a popular choice for API communication in Flutter mobile development. Unlike REST, GraphQL provides a single endpoint with flexible queries, reducing bandwidth and improving performance. In this tutorial, you’ll learn how to integrate a GraphQL API into your Flutter app using the graphql_flutter package. We’ll cover client setup, schema mapping, crafting queries and mutations, response handling with caching, and rendering data in widgets.
Setting Up the GraphQL Client
Start by adding graphql_flutter and gql to your pubspec.yaml. Then wrap your app in a GraphQLProvider and initialize a client with a link and cache. The client link handles HTTP communication, while the cache uses normalized in-memory storage for offline support.
final HttpLink httpLink = HttpLink('https://api.example.com/graphql');
ValueNotifier<GraphQLClient> client = ValueNotifier(
GraphQLClient(
link: httpLink,
cache: GraphQLCache(store: InMemoryStore()),
),
);
void main() => runApp(
GraphQLProvider(
client: client,
child: MyApp(),
),
);
Defining Schemas and Models
In GraphQL, you define types on the server, but in Flutter you can create Dart models to map the JSON response. Use code generation or manual parsing with json_serializable
. Define classes matching your query fields to ensure type safety and cleaner parsing.
class User {
final String id;
final String name;
User({required this.id, required this.name});
factory User.fromJson(Map<String, dynamic> json) {
return User(
id: json['id'],
name: json['name'],
);
}
}
This model maps directly to the server schema’s User type, simplifying serialization.
Writing Queries and Mutations
Use the gql
tag to define your operations. Queries fetch data, while mutations modify it. Keep queries concise, selecting only necessary fields.
final String fetchUsers = gql('''
query FetchUsers {
users {
id
name
}
}
''');
final String addUser = gql('''
mutation AddUser($name: String!) {
createUser(input: {name: $name}) {
id
name
}
}
''');
Wrap these in Query
or Mutation
widgets or use the client’s query
and mutate
methods in your business logic.
Handling Responses and Caching
The graphql_flutter client normalizes and caches responses automatically. Use Query
widgets to reactively rebuild on cache updates. Check result.isLoading
, result.data
, and result.exception
to manage UI states. For manual queries:
final QueryResult result = await client.value.query(
QueryOptions(document: fetchUsers),
);
if (result.hasException) {
print(result.exception.toString());
} else {
List usersJson = result.data!['users'];
List<User> users = usersJson.map((u) => User.fromJson(u)).toList();
}
Leverage fetchPolicy
to control network vs. cache behavior: cacheFirst
, networkOnly
, or cacheAndNetwork
.
Integrating with Widgets
In Flutter, wrap UI elements with Query
or Mutation
builders. Handle loading and error states in builders, returning spinners or error messages. Once data arrives, map JSON to Dart models and render with standard widgets like ListView.
Query(
options: QueryOptions(document: fetchUsers),
builder: (result, {fetchMore, refetch}) {
if (result.isLoading) return CircularProgressIndicator();
if (result.hasException) return Text('Error');
final users = (result.data!['users'] as List)
.map((u) => User.fromJson(u))
.toList();
return ListView(
children: users.map((u) => Text(u.name)).toList(),
);
},
);
This pattern keeps UI and data logic separate and reactive.
Vibe Studio

Vibe Studio, powered by Steve’s advanced AI agents, is a revolutionary no-code, conversational platform that empowers users to quickly and efficiently create full-stack Flutter applications integrated seamlessly with Firebase backend services. Ideal for solo founders, startups, and agile engineering teams, Vibe Studio allows users to visually manage and deploy Flutter apps, greatly accelerating the development process. The intuitive conversational interface simplifies complex development tasks, making app creation accessible even for non-coders.
Conclusion
Integrating GraphQL in Flutter enhances mobile development by reducing over-fetching and consolidating endpoints. With graphql_flutter, you get built-in caching, query management, and widget integration. By defining Dart models for schema types, crafting precise queries and mutations, handling responses with policies, and rendering data in widgets, you’ll build responsive, efficient apps with a modern API approach. Start experimenting today to see immediate gains in performance and developer experience.
Introduction
GraphQL has become a popular choice for API communication in Flutter mobile development. Unlike REST, GraphQL provides a single endpoint with flexible queries, reducing bandwidth and improving performance. In this tutorial, you’ll learn how to integrate a GraphQL API into your Flutter app using the graphql_flutter package. We’ll cover client setup, schema mapping, crafting queries and mutations, response handling with caching, and rendering data in widgets.
Setting Up the GraphQL Client
Start by adding graphql_flutter and gql to your pubspec.yaml. Then wrap your app in a GraphQLProvider and initialize a client with a link and cache. The client link handles HTTP communication, while the cache uses normalized in-memory storage for offline support.
final HttpLink httpLink = HttpLink('https://api.example.com/graphql');
ValueNotifier<GraphQLClient> client = ValueNotifier(
GraphQLClient(
link: httpLink,
cache: GraphQLCache(store: InMemoryStore()),
),
);
void main() => runApp(
GraphQLProvider(
client: client,
child: MyApp(),
),
);
Defining Schemas and Models
In GraphQL, you define types on the server, but in Flutter you can create Dart models to map the JSON response. Use code generation or manual parsing with json_serializable
. Define classes matching your query fields to ensure type safety and cleaner parsing.
class User {
final String id;
final String name;
User({required this.id, required this.name});
factory User.fromJson(Map<String, dynamic> json) {
return User(
id: json['id'],
name: json['name'],
);
}
}
This model maps directly to the server schema’s User type, simplifying serialization.
Writing Queries and Mutations
Use the gql
tag to define your operations. Queries fetch data, while mutations modify it. Keep queries concise, selecting only necessary fields.
final String fetchUsers = gql('''
query FetchUsers {
users {
id
name
}
}
''');
final String addUser = gql('''
mutation AddUser($name: String!) {
createUser(input: {name: $name}) {
id
name
}
}
''');
Wrap these in Query
or Mutation
widgets or use the client’s query
and mutate
methods in your business logic.
Handling Responses and Caching
The graphql_flutter client normalizes and caches responses automatically. Use Query
widgets to reactively rebuild on cache updates. Check result.isLoading
, result.data
, and result.exception
to manage UI states. For manual queries:
final QueryResult result = await client.value.query(
QueryOptions(document: fetchUsers),
);
if (result.hasException) {
print(result.exception.toString());
} else {
List usersJson = result.data!['users'];
List<User> users = usersJson.map((u) => User.fromJson(u)).toList();
}
Leverage fetchPolicy
to control network vs. cache behavior: cacheFirst
, networkOnly
, or cacheAndNetwork
.
Integrating with Widgets
In Flutter, wrap UI elements with Query
or Mutation
builders. Handle loading and error states in builders, returning spinners or error messages. Once data arrives, map JSON to Dart models and render with standard widgets like ListView.
Query(
options: QueryOptions(document: fetchUsers),
builder: (result, {fetchMore, refetch}) {
if (result.isLoading) return CircularProgressIndicator();
if (result.hasException) return Text('Error');
final users = (result.data!['users'] as List)
.map((u) => User.fromJson(u))
.toList();
return ListView(
children: users.map((u) => Text(u.name)).toList(),
);
},
);
This pattern keeps UI and data logic separate and reactive.
Vibe Studio

Vibe Studio, powered by Steve’s advanced AI agents, is a revolutionary no-code, conversational platform that empowers users to quickly and efficiently create full-stack Flutter applications integrated seamlessly with Firebase backend services. Ideal for solo founders, startups, and agile engineering teams, Vibe Studio allows users to visually manage and deploy Flutter apps, greatly accelerating the development process. The intuitive conversational interface simplifies complex development tasks, making app creation accessible even for non-coders.
Conclusion
Integrating GraphQL in Flutter enhances mobile development by reducing over-fetching and consolidating endpoints. With graphql_flutter, you get built-in caching, query management, and widget integration. By defining Dart models for schema types, crafting precise queries and mutations, handling responses with policies, and rendering data in widgets, you’ll build responsive, efficient apps with a modern API approach. Start experimenting today to see immediate gains in performance and developer experience.
Build Flutter Apps Faster with Vibe Studio
Build Flutter Apps Faster with Vibe Studio
Build Flutter Apps Faster with Vibe Studio
Build Flutter Apps Faster with Vibe Studio
Vibe Studio is your AI-powered Flutter development companion. Skip boilerplate, build in real-time, and deploy without hassle. Start creating apps at lightning speed with zero setup.
Vibe Studio is your AI-powered Flutter development companion. Skip boilerplate, build in real-time, and deploy without hassle. Start creating apps at lightning speed with zero setup.
Vibe Studio is your AI-powered Flutter development companion. Skip boilerplate, build in real-time, and deploy without hassle. Start creating apps at lightning speed with zero setup.
Vibe Studio is your AI-powered Flutter development companion. Skip boilerplate, build in real-time, and deploy without hassle. Start creating apps at lightning speed with zero setup.











