I've created a graphql-codegen plugin that generates type-safe hooks for GraphQL queries for Flutter!
seya
Posted on January 1, 2022
If you are a Flutter & GraphQL fan, please try it.
(And if you like it, please give it a star ⭐️)
https://github.com/kazuyaseki/graphql-codegen-flutter-artemis-hooks
Motivation
I'm from React, and when building an application with React + Apollo configuration, I really liked the experience of using graphql-codegen to generate hooks like this
export function useFetchUserQuery(baseOptions?: ApolloReactHooks.QueryHookOptions<FetchUserQuery, FetchUserQueryVariables>) {
return ApolloReactHooks.useQuery<FetchUserQuery, FetchUserQueryVariables>(FetchUserDocument, baseOptions);
}
(This is the code that will be generated when you use this plugin with withHooks
set to true.)
https://www.graphql-code-generator.com/plugins/typescript-react-apollo
I want to develop with the same experience in Flutter! So I created this plugin.
https://github.com/kazuyaseki/graphql-codegen-flutter-artemis-hooks
In Flutter, there is a library called artemis that generates the type definitions, so this plugin is based on that.
For example, suppose you define a query like this as a .graphql file
query ExampleQuery {
objects {
id
name
}
}
mutation TestMutation($variable: String!) {
testMutation(variable: $variable) {
result
}
}
This plugin will generate the following hooks function
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:gql/ast.dart';
import 'package:your_project/your_artemis_generated/graphql_api.dart';
QueryResult useQuery<DataType>(BuildContext context, DocumentNode query,
[Map<String, dynamic>? variables]) {
final client = GraphQLProvider.of(context).value;
final state =
useState<QueryResult>(QueryResult(source: QueryResultSource.network));
useEffect(() {
late Future<QueryResult> promise;
if (variables ! = null) {
promise = client.query(
QueryOptions(document: query, variables: variables),
);
} else {
promise = client.query(
QueryOptions(document: query),
);
}
promise.then((result) {
state.value = result;
});
return () {};
}, []);
return state.value;
}
class ExampleQuery$QueryReturnType {
bool isLoading;
OperationException? exception;
ExampleQuery$Query? data;
ExampleQuery$QueryReturnType(this.isLoading, this.exception, this.data);
}
ExampleQuery$QueryReturnType useExampleQueryQuery<DataType>(BuildContext context) {
final result = useQuery<ExampleQuery$Query>(context, EXAMPLE_QUERY_QUERY_DOCUMENT);
return ExampleQuery$QueryReturnType(result.isLoading, result.exception, result.data == null ? null : ExampleQuery$Query.fromJson(result.data!));
}
class TestMutation$MutationReturnType {
bool isLoading;
OperationException? exception;
TestMutation$Mutation? data;
TestMutation$MutationReturnType(this.isLoading, this.exception, this.data);
}
TestMutation$MutationReturnType useTestMutationQuery<DataType>(BuildContext context, TestMutationArguments variables) {
final result = useQuery<TestMutation$Mutation>(context, TEST_MUTATION_MUTATION_DOCUMENT, variables.toJson());
return TestMutation$MutationReturnType(result.isLoading, result.exception, result.data == null ? null : TestMutation$Mutation.fromJson(result.data!));
}
Then all that's left to do is import the above file and use the hooks! 🔥
class PageWidget extends HookWidget {
const PageWidget({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
final queryResult = useExampleQueryQuery(context);
final mutationResult = useTestMutationQuery(context, TestMutationArguments(variable: ""));
return ...
}
}
Usage
Installation
npm i --save-dev graphql-codegen-flutter-artemis-hooks
Create a configuration file for graphql-codegen.
Create a configuration file for graphql-codegen, including the schema, the path to the .graphql file, and the path to the artemis-generated file.
schema: your_schema_file.graphql
documents: '. /your_project/**/*.graphql'.
generates:
your_project/generated_hooks.dart:
config:
artemisImportPath: package:your_project/your_artemis_generated/graphql_api.dart
plugins:
- graphql-codegen-flutter-artemis-hooks
Run graphql-codegen
If you do not have graphql-codegen itself installed, install the following @graphql-codegen/cli
.
npm i --save-dev @graphql-codegen/cli
Then add the following script to package.json and run npm run codegen
!
{
"scripts": {
"codegen": "graphql-codegen"
},
}
That's it, I hope you find it useful!
Posted on January 1, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.