Open15

Flutter / graphql_codegenでコード生成

aoshima214aoshima214

codegenのReadmeのとおりにSchemaを設置して ↓のコマンドを打ってみる

dart run build_runner build

が、何も生成されない

aoshima214aoshima214

libの配下に .graphql を配置すると生成できた

person.graphql.dart
import 'package:gql/ast.dart';
import 'package:json_annotation/json_annotation.dart';
part 'person.graphql.g.dart';

(explicitToJson: true)
class VariablesQueryFetchPerson {
  VariablesQueryFetchPerson({required this.id});

  
  factory VariablesQueryFetchPerson.fromJson(Map<String, dynamic> json) =>
      _$VariablesQueryFetchPersonFromJson(json);

  final String id;

  Map<String, dynamic> toJson() => _$VariablesQueryFetchPersonToJson(this);
  int get hashCode {
    final l$id = id;
    return Object.hashAll([l$id]);
  }

  
  bool operator ==(Object other) {
    if (identical(this, other)) return true;
    if (!(other is VariablesQueryFetchPerson) ||
        runtimeType != other.runtimeType) return false;
    final l$id = id;
    final lOther$id = other.id;
    if (l$id != lOther$id) return false;
    return true;
  }
}

(explicitToJson: true)
class QueryFetchPerson {
  QueryFetchPerson({this.fetch_person, required this.$__typename});

  
  factory QueryFetchPerson.fromJson(Map<String, dynamic> json) =>
      _$QueryFetchPersonFromJson(json);

  final QueryFetchPerson$fetchPerson? fetch_person;

  (name: '__typename')
  final String $__typename;

  Map<String, dynamic> toJson() => _$QueryFetchPersonToJson(this);
  int get hashCode {
    final l$fetch_person = fetch_person;
    final l$$__typename = $__typename;
    return Object.hashAll([l$fetch_person, l$$__typename]);
  }

  
  bool operator ==(Object other) {
    if (identical(this, other)) return true;
    if (!(other is QueryFetchPerson) || runtimeType != other.runtimeType)
      return false;
    final l$fetch_person = fetch_person;
    final lOther$fetch_person = other.fetch_person;
    if (l$fetch_person != lOther$fetch_person) return false;
    final l$$__typename = $__typename;
    final lOther$$__typename = other.$__typename;
    if (l$$__typename != lOther$$__typename) return false;
    return true;
  }
}

extension UtilityExtensionQueryFetchPerson on QueryFetchPerson {
  QueryFetchPerson copyWith(
          {QueryFetchPerson$fetchPerson? Function()? fetch_person,
          String? $__typename}) =>
      QueryFetchPerson(
          fetch_person:
              fetch_person == null ? this.fetch_person : fetch_person(),
          $__typename: $__typename == null ? this.$__typename : $__typename);
}

const QUERY_FETCH_PERSON = const DocumentNode(definitions: [
  OperationDefinitionNode(
      type: OperationType.query,
      name: NameNode(value: 'FetchPerson'),
      variableDefinitions: [
        VariableDefinitionNode(
            variable: VariableNode(name: NameNode(value: 'id')),
            type: NamedTypeNode(name: NameNode(value: 'ID'), isNonNull: true),
            defaultValue: DefaultValueNode(value: null),
            directives: [])
      ],
      directives: [],
      selectionSet: SelectionSetNode(selections: [
        FieldNode(
            name: NameNode(value: 'fetch_person'),
            alias: null,
            arguments: [
              ArgumentNode(
                  name: NameNode(value: 'id'),
                  value: VariableNode(name: NameNode(value: 'id')))
            ],
            directives: [],
            selectionSet: SelectionSetNode(selections: [
              FieldNode(
                  name: NameNode(value: 'full_name'),
                  alias: NameNode(value: 'name'),
                  arguments: [],
                  directives: [],
                  selectionSet: null),
              FieldNode(
                  name: NameNode(value: '__typename'),
                  alias: null,
                  arguments: [],
                  directives: [],
                  selectionSet: null)
            ])),
        FieldNode(
            name: NameNode(value: '__typename'),
            alias: null,
            arguments: [],
            directives: [],
            selectionSet: null)
      ])),
]);

(explicitToJson: true)
class QueryFetchPerson$fetchPerson {
  QueryFetchPerson$fetchPerson({required this.name, required this.$__typename});

  
  factory QueryFetchPerson$fetchPerson.fromJson(Map<String, dynamic> json) =>
      _$QueryFetchPerson$fetchPersonFromJson(json);

  final String name;

  (name: '__typename')
  final String $__typename;

  Map<String, dynamic> toJson() => _$QueryFetchPerson$fetchPersonToJson(this);
  int get hashCode {
    final l$name = name;
    final l$$__typename = $__typename;
    return Object.hashAll([l$name, l$$__typename]);
  }

  
  bool operator ==(Object other) {
    if (identical(this, other)) return true;
    if (!(other is QueryFetchPerson$fetchPerson) ||
        runtimeType != other.runtimeType) return false;
    final l$name = name;
    final lOther$name = other.name;
    if (l$name != lOther$name) return false;
    final l$$__typename = $__typename;
    final lOther$$__typename = other.$__typename;
    if (l$$__typename != lOther$$__typename) return false;
    return true;
  }
}

extension UtilityExtensionQueryFetchPerson$fetchPerson
    on QueryFetchPerson$fetchPerson {
  QueryFetchPerson$fetchPerson copyWith({String? name, String? $__typename}) =>
      QueryFetchPerson$fetchPerson(
          name: name == null ? this.name : name,
          $__typename: $__typename == null ? this.$__typename : $__typename);
}

aoshima214aoshima214

Queryオブジェクトは特殊なオブジェクトです。
省略されていますが実は、

schema {
    query: Query
    mutation: Mutation
}

という定義がデフォルトでされています。

aoshima214aoshima214

Queryの引数のオブジェクトは input を使って宣言する

aoshima214aoshima214

https://pub.dev/packages/graphql_codegen

Installation #
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.

json_serializableの設定しろって一番上に書いてあった

aoshima214aoshima214
pubspec.yaml
dependencies:
  json_annotation: 4.5.0

dev_dependencies:
  graphql_codegen: 0.8.0
  json_serializable: 6.2.0
  build_runner: 2.1.11
aoshima214aoshima214

自動生成コードをanalyzerから除外

analysis_options.yaml
analyzer:
  exclude:
    - lib/**/*.g.dart
    - lib/**/*.graphql.dart
aoshima214aoshima214
  • schema.graphql.dart
  • schema.graphql.g.dart
    ↑が生成された。中身は shema.graphql の input の変換
aoshima214aoshima214

dart run build_runner build でコード生成時にコンソールにエラー

This builder requires Dart inputs without syntax errors.
This requires the 'super-parameters' language feature to be enabled.
Try fixing the errors and re-running the build.
aoshima214aoshima214
[WARNING] graphql_codegen:graphql_codegen on lib/graphql/query/healthCheck.graphql:
Missing scalar DateTime. Defaulting to String
aoshima214aoshima214

Custom Scalar
https://pub.dev/packages/graphql_codegen#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: