Unions
Similar to enums, Unions are restricted to a set of predefined variants, however the possible types are always the more complex GraphQLObjectType
.
Per the GraphQL spec, Unions can't be (or be part of) Input types and their possible types is a non empty collection of unique GraphQLObjectType
.
To have the following GraphQL type definitions:
union ModelEvent = ModelAdded | ModelRemoved
type ModelRemoved {
"The removed model id"
modelId: ID!
}
type ModelAdded {
model: Model!
}
type Model {
id: ID!
}
You could provide this definitions:
import 'package:leto_schema/leto_schema.dart';
final model = objectType(
'Model',
fields: [
graphQLIdType.nonNull().field('id'),
],
);
final modelAddedGraphQLType = objectType(
'ModelAdded',
fields: [model.nonNull().field('model')],
);
final modelRemovedGraphQLType = objectType(
'ModelRemoved',
fields: [graphQLIdType.nonNull().field('modelId')],
);
final union = GraphQLUnionType(
// name
'ModelEvent',
// possibleTypes
[
modelAddedGraphQLType,
modelRemovedGraphQLType,
],
);
extractInner
When the members of the union type are not
Freezed Unions
With code generation, Unions with freezed also work without trouble.
import 'package:leto_schema/leto_schema.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
()
class Model {
final String id;
const Model(this.id);
}
()
class ModelEvent with _$ModelEvent {
const factory ModelEvent.added(Model model) = ModelAdded;
const factory ModelEvent.removed(
(type: 'graphQLIdType', description: 'The removed model id')
String modelId,
// you can also provide a private class
) = _ModelRemoved;
}
GraphQLAttachments unionNoFreezedAttachments() => const [ElementComplexity(50)];
(unionNoFreezedAttachments)
(
description: '''
Description from annotation.
Union generated from raw Dart classes''',
)
(name: 'UnionNoFreezedRenamed')
class UnionNoFreezed {
const factory UnionNoFreezed.a(String value) = UnionNoFreezedA.named;
const factory UnionNoFreezed.b(int value) = UnionNoFreezedB;
}
()
class UnionNoFreezedA implements UnionNoFreezed {
final String value;
const UnionNoFreezedA.named(this.value);
}
()
class UnionNoFreezedB implements UnionNoFreezed {
final int value;
const UnionNoFreezedB(this.value);
}
()
List<UnionNoFreezed> getUnionNoFrezzed() {
return const [UnionNoFreezed.a('value'), UnionNoFreezed.b(12)];
}