Unions
Les types d’union sont très similaires aux interfaces, mais ils ne permettent pas de spécifier des champs communs entre les types (lisez-en plus ici). Les unions sont utiles pour retourner des types de données disjoints à partir d’un champ unique.
Code premier
Pour définir un type d’union GraphQL, nous devons définir des classes dont cette union sera composée. En suivant l’exemple de la documentation d’Apollo, nous allons créer deux classes. D’abord, Book
:
import { Field, ObjectType } from '@nestjs/graphql';
@ObjectType()export class Book { @Field() title: string;}
Et ensuite Author
:
import { Field, ObjectType } from '@nestjs/graphql';
@ObjectType()export class Author { @Field() name: string;}
Avec cela en place, enregistrez l’union ResultUnion
en utilisant la fonction createUnionType
exportée du paquet @nestjs/graphql
:
export const ResultUnion = createUnionType({ name: 'ResultUnion', types: () => [Author, Book] as const,});
Maintenant, nous pouvons référencer ResultUnion
dans notre requête :
@Query(returns => [ResultUnion])search(): Array<typeof ResultUnion> { return [new Author(), new Book()];}
Cela va générer la partie suivante du schéma GraphQL en SDL :
type Author { name: String!}
type Book { title: String!}
union ResultUnion = Author | Book
type Query { search: [ResultUnion!]}
La fonction par défaut resolveType()
générée par la bibliothèque extraira le type en fonction de la valeur retournée par la méthode résolveur. Cela signifie que retourner des instances de classe au lieu d’objets JavaScript littéraux est obligatoire.
Pour fournir une fonction resolveType()
personnalisée, passez la propriété resolveType
à l’objet d’options passé dans la fonction createUnionType()
, comme suit :
export const ResultUnion = createUnionType({ name: 'ResultUnion', types: () => [Author, Book] as const, resolveType(value) { if (value.name) { return Author; } if (value.title) { return Book; } return null; },});
Schéma premier
Pour définir une union dans l’approche schéma premier, créez simplement une union GraphQL avec SDL.
type Author { name: String!}
type Book { title: String!}
union ResultUnion = Author | Book
Ensuite, vous pouvez utiliser la fonctionnalité de génération de types (comme montré dans le chapitre de démarrage rapide) pour générer les définitions TypeScript correspondantes :
export class Author { name: string;}
export class Book { title: string;}
export type ResultUnion = Author | Book;
Les unions nécessitent un champ __resolveType
supplémentaire dans la carte du résolveur pour déterminer quel type l’union doit résoudre. Notez également que la classe ResultUnionResolver
doit être enregistrée en tant que fournisseur dans n’importe quel module. Créons une classe ResultUnionResolver
et définissons la méthode __resolveType
.
@Resolver('ResultUnion')export class ResultUnionResolver { @ResolveField() __resolveType(value) { if (value.name) { return 'Author'; } if (value.title) { return 'Book'; } return null; }}
Énumérations
Les types d’énumération sont un type spécial de scalaire qui est restreint à un ensemble particulier de valeurs autorisées (lisez-en plus ici). Cela vous permet de :
- valider que tous les arguments de ce type sont l’une des valeurs autorisées
- communiquer à travers le système de types qu’un champ sera toujours l’un d’un ensemble fini de valeurs
Code premier
Lors de l’utilisation de l’approche premier code, vous définissez un type d’énumération GraphQL simplement en créant une énumération TypeScript.
export enum AllowedColor { RED, GREEN, BLUE,}
Avec cela en place, enregistrez l’énumération AllowedColor
en utilisant la fonction registerEnumType
exportée du paquet @nestjs/graphql
:
registerEnumType(AllowedColor, { name: 'AllowedColor',});
Maintenant, vous pouvez référencer AllowedColor
dans nos types :
@Field(type => AllowedColor)favoriteColor: AllowedColor;
Cela va générer la partie suivante du schéma GraphQL en SDL :
enum AllowedColor { RED GREEN BLUE}
Pour fournir une description pour l’énumération, passez la propriété description
dans la fonction registerEnumType()
.
registerEnumType(AllowedColor, { name: 'AllowedColor', description: 'Les couleurs supportées.',});
Pour fournir une description pour les valeurs de l’énumération, ou pour marquer une valeur comme obsolète, passez la propriété valuesMap
, comme suit :
registerEnumType(AllowedColor, { name: 'AllowedColor', description: 'Les couleurs supportées.', valuesMap: { RED: { description: 'La couleur par défaut.', }, BLUE: { deprecationReason: 'Trop bleu.', }, },});
Cela générera le schéma GraphQL suivant en SDL :
"""Les couleurs supportées."""enum AllowedColor { """La couleur par défaut.""" RED GREEN BLUE @deprecated(reason: "Trop bleu.")}
Schéma premier
Pour définir un énumérateur dans l’approche schéma premier, créez simplement une énumération GraphQL avec SDL.
enum AllowedColor { RED GREEN BLUE}
Ensuite, vous pouvez utiliser la fonctionnalité de génération de types (comme montré dans le chapitre de démarrage rapide) pour générer les définitions TypeScript correspondantes :
export enum AllowedColor { RED, GREEN, BLUE,}
Parfois, un backend impose une valeur différente pour une énumération en interne par rapport à l’API publique. Dans cet exemple, l’API contient RED
, cependant dans les résolveurs, nous pouvons utiliser #f00
à la place (lisez-en plus ici). Pour ce faire, déclarez un objet résolveur pour l’énumération AllowedColor
:
export const allowedColorResolver: Record<keyof typeof AllowedColor, any> = { RED: '#f00',};
Utilisez ensuite cet objet résolveur avec la propriété resolvers
de la méthode GraphQLModule#forRoot()
, comme suit :
GraphQLModule.forRoot({ resolvers: { AllowedColor: allowedColorResolver, },});