Skip to main content

Dart Type to GraphQLType coercion

Dart types specified as fields of classes or input parameters in resolvers will be coerced into GraphQLTypes using the following rules.

Default type mappings

Dart TypeGraphQL Type
StringString
intInt
double/numFloat
boolBoolean
String/int (with id as name, configurable)ID
List<T>[T]
DateTimeDate (custom scalar)
UriUri (custom scalar)
BigIntBigInt (custom scalar)

By default, a non-nullable Dart String (or any type) represents a GraphQL String! and a nullable Dart String? represents a GraphQL String, however that can be configured for each field, class or for the whole project.

Provided type annotations

Using the provided type annotations, a GraphQLType will be created for the given class or enum. You can use any type with a type annotation as part of another type or in the definition of a resolver function.

Class.graphQLType static getter

If you have control over the class definition, you can provide a static graphQLType getter in the class. This will be used as the GraphQL type in other parts of code generation.

Typically used for scalar types that you control (not from another package) or for generic types that need more customization (usage of GraphQLUnionType.extractInner for example).

Some examples of this are the Json, PageInfo and Result<T, E> provided types.

It is important when using a static graphQLType getter that it returns the same GraphQLType instance each time it is called. This prevents Leto from the same seeing a different GraphQLType each time the type is used and creating a cyclical dependency. An example:

final fooGraphQLType = GraphQLScalarTypeValue<Foo, String>(
name: 'Foo',
deserialize: (_, serialized) => fooFromJson(serialized)!,
serialize: (value) => fooToJson(value)!,
validate: (key, input) => (input is String)
? ValidationResult.ok(input)
: ValidationResult.failure(
['Expected $key to be a String.'],
),
description: 'A Foo.',
specifiedByURL: null,
);

Foo? fooFromJson(Object? value) => value == null ? null : Foo(value.toString());

String? fooToJson(Foo? value) => value?.bar;

class Foo {
String bar;
Foo(this.bar);
static GraphQLScalarTypeValue<Foo, String> get graphQLType => fooGraphQLType;
}

customTypes in build.yaml

Another way of mapping a Dart type to a GraphQLType instance is by using the "customTypes" build.yaml global config option explained in the customTypes section. This will override (take precedence over) all other type mappings.

Useful for types that you don't control like the Decimal type from https://github.com/a14n/dart-decimal or IsoDuration from https://github.com/mzdm/iso_duration_parser.

@GraphQLDocumentation(type: Function, typeName: String)

If you want to customize a single field or argument with a GraphQLType different from the one inferred by the library, you can provide a static function (GraphQLType Function()) which returns the expected type in the type parameter of @GraphQLDocumentation(type: ). For the same purpose, we provide a typeName String value, which should be the getter (in Dart code) of the expected GraphQLType. The code generation will throw an exception if you provide both at the same time.