Build dart types from GraphQL schemas and queries
Check the beta branch for the bleeding edge (and breaking) stuff.
Artemis is a code generator that looks for schema.graphql
(GraphQL SDL - Schema Definition Language) and *.graphql
files and builds .graphql.dart
files typing that query, based on the schema. That's similar to what Apollo does (Artemis is his sister anyway).
Add the following to your pubspec.yaml
file to be able to do code generation:
dev_dependencies:
artemis: '>=7.0.0 <8.0.0'
build_runner: ^2.1.4
json_serializable: ^6.0.1
The generated code uses the following packages in run-time:
dependencies:
artemis: '>=8.0.0 <8.0.0' # only if you're using ArtemisClient!
json_annotation: ^4.3.0
equatable: ^2.0.3
gql: ^0.13.1-alpha
Then run:
dart pub get
or
flutter pub get
Now Artemis will generate the API files for you by running:
dart run build_runner build
or
flutter pub run build_runner build
Artemis offers some configuration options to generate code. All options should be included on build.yaml
file on the root of the project:
targets:
$default:
builders:
artemis:
options:
# custom configuration options!
⚠️ Make sure your configuration file is calledbuild.yaml
(with.yaml
extension, not.yml
)!
| Option | Default value | Description | | - | - | - | | generate_helpers
| true
| If Artemis should generate
query/mutation helper GraphQLQuery subclasses. | | generate_queries
| true
| If Artemis should generate query
documents and operation names. If you are using Artemis with graphql
library it is useful to have those queries and
operation names generated but without Atremis specific classes to exclude Artemis from dependancies | | scalar_mapping
| []
| Mapping of GraphQL and Dart types. See Custom scalars. | | schema_mapping
| []
| Mapping
of queries and which schemas they will use for code generation. See Schema mapping. |
| fragments_glob
| null
| Import path to the file implementing fragments for all queries mapped in schema_mapping.
If it's assigned, fragments defined in schema_mapping will be ignored. | | ignore_for_file
| []
| The linter rules
to ignore for artemis generated files. |
It's important to remember that, by default, build will
follow Dart's package layout conventions, meaning that only some folders
will be considered to parse the input files. So, if you want to reference files from a folder other than lib/
, make
sure you've included it on sources
:
targets:
$default:
sources:
- lib/**
- graphql/**
- data/**
- schema.graphql
By default, Artemis won't generate anything. That's because your queries/mutations should be linked to GraphQL schemas. To configure it, you need to point a schema_mapping
to the path of those queries and schemas:
targets:
$default:
builders:
artemis:
options:
schema_mapping:
- output: lib/graphql_api.graphql.dart
schema: lib/my_graphql_schema.graphql
queries_glob: lib/**.graphql
Each SchemaMap
is configured this way:
Option | Default value | Description |
---|---|---|
output |
Relative path to output the generated code. It should end with .graphql.dart or else the generator will need to generate one more file. |
|
schema |
Relative path to the GraphQL schema. | |
queries_glob |
Glob that selects all query files to be used with this schema. | |
naming_scheme |
pathedWithTypes |
The naming scheme to be used on generated classes names. pathedWithTypes is the default for retrocompatibility, where the names of previous types are used as prefix of the next class. This can generate duplication on certain schemas. With pathedWithFields , the names of previous fields are used as prefix of the next class and with simple , only the actual GraphQL class nameis considered. |
type_name_field |
__typename |
The name of the field used to differentiate interfaces and union types (commonly __typename or __resolveType ). Note that __typename field are not added automatically to the query. If you want interface/union type resolution, you need to manually add it there or set append_type_name to true . |
append_type_name |
false |
Appends type_name_field value to the query selections set. |
fragments_glob |
null |
Import path to the file implementing fragments for all queries mapped in schema_mapping. |
See examples for more information and configuration options.
If your schema uses custom scalars, they must be defined on build.yaml
. If it needs a custom parser (to decode from/to json), the custom_parser_import
path must be set and the file must implement both fromGraphQL___ToDart___
and fromDart___ToGraphQL___
constant functions.
___ToDart___
and ___ToGraphQL___
should be named including nullability, here is an example:
file: Upload
=>fromGraphQLUploadNullableToDartMultipartFileNullable
andfromDartMultipartFileNullableToGraphQLUploadNullable
file: Upload!
=>fromGraphQLUploadToDartMultipartFile
andfromDartMultipartFileToGraphQLUpload
file: [Upload]
=>fromGraphQLListNullableUploadNullableToDartListNullableMultipartFileNullable
andfromDartListNullableMultipartFileNullableToGraphQLListNullableUploadNullable
file: [Upload]!
=>fromGraphQLListUploadNullableToDartListMultipartFileNullable
andfromDartListMultipartFileNullableToGraphQLListUploadNullable
file: [Upload!]!
=>fromGraphQLListUploadToDartListMultipartFile
andfromDartListMultipartFileToGraphQLListUpload
targets:
$default:
builders:
artemis:
options:
scalar_mapping:
- custom_parser_import: 'package:graphbrainz_example/coercers.dart'
graphql_type: Date
dart_type: DateTime
If your custom scalar needs to import Dart libraries, you can provide it in the config as well:
targets:
$default:
builders:
artemis:
options:
scalar_mapping:
- custom_parser_import: 'package:graphbrainz_example/coercers.dart'
graphql_type: BigDecimal
dart_type:
name: Decimal
imports:
- 'package:decimal/decimal.dart'
Each ScalarMap
is configured this way:
Option | Default value | Description |
---|---|---|
graphql_type |
The GraphQL custom scalar name on schema. | |
dart_type |
The Dart type this custom scalar should be converted from/to. | |
custom_parser_import |
null |
Import path to the file implementing coercer functions for custom scalars. See Custom scalars. |
See examples for more information and configuration options.
If you have generate_helpers
, Artemis will create a subclass of GraphQLQuery
for you, this class can be used
in conjunction with ArtemisClient
.
final client = ArtemisClient('/graphql');
final gitHubReposQuery = MyGitHubReposQuery();
final response = await client.execute(gitHubReposQuery);
ArtemisClient
adds type-awareness around Link
from package:gql/link
.
You can create ArtemisClient
from any Link
using ArtemisClient.fromLink
.
Check the examples to see how to use it in details.