graphql_codegen 0.4.1 copy "graphql_codegen: ^0.4.1" to clipboard
graphql_codegen: ^0.4.1 copied to clipboard

outdated

Simple, opinionated, codegen library for GraphQL. It allows you to generate serializers and client helpers to easily call and parse your data.

GraphQL Codegen #

This is an opinionated code-generation tool from GraphQL to Dart/Flutter.

It'll allow you to generate Dart serializers and client helpers with minimal config. The framework makes no assumption on how you structure your fragments or queries, for each operation.graphql the framework will generate a operation.graphq.dart file containing dart classes.

The builder relies on json_serializable to generate the actual serializers, so in addition to the two files mentioned above, it'll also generate a operation.graphql.g.dart file.

The framework does not fetch your schema for you, so before you run this, you'll need to add your schema to your project.

Setup #

Add graphql_codegen: <current_version> to your dev_dependencies.

The project depends on json_serializable so read more on how to set this up here. It is also a builder, so you'll need to set up build_runner. Read more here.

When you've setup the builder, you can generate your code with:

$ dart run build_runner build

Writing GraphQL files #

Given schema

# schema.graphql

type Query {
    fetch_person(id: ID!): Person
}

type Person {
    full_name: String!
    nickname: String
    website: URL
    date_of_birth: ISODateTime
    parents: [Person!]
    siblings: [Person!]
    children: [Person!]    
}

scalar ISODateTime

scalar URL

and a query

# person.graphql

query FetchPerson ($id: ID!) {
    fetch_person(id: $id) {
        name: full_name
    }
}

you can parse the result with

// person.dart

import 'person.graphql.dart';

main () {
    final data = fetchDataFromSomewhereMaybeOuterSpace();
    final parsedData = QueryFetchPerson.fromJson(data);
    final name = parsedData.fetchPerson?.name;
    print(name);
}

Using fragments #

Fragments are a great tool to re-use queries throughout your app. These are used to create "interfaces" which'll allow you to easily parse your data around. Given the schema above and the query

# parents_and_children.graphql

fragment PersonSummary on Person {
    full_name
}

query FetchParentsAndChildren {
    fetch_person(id: "1") {
        parents {
            ...PersonSummary
            nickname
        }

        children {
            ...PersonSummary
        }
    }
}

this will allow you to do the following

// parents_and_children.dart

import 'parents_and_children.graphql.dart';

printPerson(FragmentPersonSummary person) {
    print(person.fullName);
}

main () {
    final data = fetchDataFromTheVoid();
    final parsedData = QueryFetchParentsAndChildren.fromJson(data);
    for (final parent in parsedData?.fetchPerson.parents ?? []) {
        printPerson(parent);
        print(parent.dob);
    }
    for (final child in parsedData?.fetchPerson.children ?? []) {
        printPerson(child);
    } 
}

The FragmentPersonSummary is an abstract class on the shape of

...
abstract class FragmentPersonSummary {
    String get fullName;
}
...

and will be available in the generated .graphql.dart file for the .graphql file containing the fragment.

Custom scalars #

Out of the box, the standard fragmens are supported and mapped to relevant dart types. You can add new mappings for your custom scalars or overwrite existing configurations.

In the schema above, you can see that we have defined the ISODateTime scalar. In this example, it contains a string with an iso formatted date-time string. We would like to map this to darts DateTime type by adding the following configuration to the build.yaml file:

# build.yaml

targets:
  $default:
    builders:
      graphql_codegen:
        options:
            scalars:
                ISODateTime:
                    type: DateTime

since json_serializable supports parsing DateTime from strings this is all we need to do.

Assume we want to use a custom date-time class instead (e.g. CustomDateTime) we can add

# build.yaml

targets:
  $default:
    builders:
      graphql_codegen:
        options:
            scalars:
                ISODateTime:
                    type: CustomDateTime
                    fromJsonFunctionName: customDateTimeFromJson
                    toJsonFunctionName: customDateTimeToJson
                    import: package:my_app/scalar.dart

and create a scalar.dart file with your converter functions and class.

// custom_date_time.dart
class CustomDateTime {
    final String datetime;

    CustomDateTime(this.datetime);
}

and

// scalar.dart

export 'custom_date_time.dart' show {CustomDateTime};

CustomDateTime customDateTimeFromJson(dynamic data) => CustomDateTime(data as String);
dynamic customDateTimeToJson(CustomDateTime time) => time.datetime;

and now all fields using ISODateTime will be a CustomDateTime instance.

Clients #

Parsing data is all fine and well, but practically not extremly usable. Therefor, we can generate clients to call your API.

Clients can be enabled in the build.yaml file with:

# build.yaml

targets:
  $default:
    builders:
      graphql_codegen:
        options:
            clients:
                - graphql
                - graphql_flutter

Currently, we support two clients:

Client graphql #

Once you've setup your graphql client (see pub.dev/packages/graphql), you can use GraphQL Codegen to generate new queries or mutators on the client.

With the query from above:

# person.graphql

query FetchPerson ($id: ID!) {
    fetch_person(id: $id) {
        name: full_name
    }
}

we can now access the client:

import 'person.graphql.dart';


main () async {
    final client = GraphQLClient();
    final result = await client.queryFetchPerson(
        GQLOptionsQueryFetchPerson(
            variables: VariablesQueryFetchPerson(
                id: "1",
            ),
        ),
    );
    final parsedData = result.parsedBodyQueryFetchPerson;
    print(parsedData?.fetchPerson?.name);
}

Client graphql_flutter #

Once you've setup your graphql_flutter client (see pub.dev/packages/graphql_flutter), you can use GraphQL Codegen to generate new Query or Mutation widgets.

With the query from above:

# person.graphql

query FetchPerson ($id: ID!) {
    fetch_person(id: $id) {
        name: full_name
    }
}

we can query with the widget

import 'person.graphql.dart';
import 'package:flutter/widgets.dart';

class PersonWidget extends StatelessWidget {

    @override
    Widget build(BuildContext context) {
        return GQLFQueryFetchPersion(
            options: GQLOptionsQueryFetchPerson(
                variables: VariablesQueryFetchPerson(
                    id: 'id',
                ),
            ),
            builder: (result, {fetchMore, refetch}) {
                return Text(
                    result.parsedDataQueryFetchPerson?.fetchPerson?.name ?? '...loading'
                );
            }
        );
    }

}
106
likes
0
pub points
93%
popularity

Publisher

verified publisherheft.app

Simple, opinionated, codegen library for GraphQL. It allows you to generate serializers and client helpers to easily call and parse your data.

Repository (GitHub)
View/report issues

License

unknown (LICENSE)

Dependencies

build, built_collection, code_builder, dart_style, glob, gql, gql_code_builder, graphql_codegen_config, path, recase

More

Packages that depend on graphql_codegen