Passer au contenu

Interfaces

Comme de nombreux systèmes de types, GraphQL prend en charge les interfaces. Une Interface est un type abstrait qui inclut un certain ensemble de champs qu’un type doit inclure pour mettre en œuvre l’interface (lisez-en plus ici).

Code first

Lors de l’utilisation de l’approche code first, vous définissez une interface GraphQL en créant une classe abstraite annotée avec le décorateur @InterfaceType() exporté de @nestjs/graphql.

Définition de l'interface Character
import { Field, ID, InterfaceType } from '@nestjs/graphql';
@InterfaceType()
export abstract class Character {
@Field((type) => ID)
id: string;
@Field()
name: string;
}

Cela entraînera la génération de la partie suivante du schéma GraphQL en SDL :

interface Character {
id: ID!
name: String!
}

Maintenant, pour mettre en œuvre l’interface Character, utilisez la clé implements :

Implémentation de l'interface Character
@ObjectType({ implements: [Character] })
export class Human implements Character {
id: string;
name: string;
}

La fonction resolveType() par défaut générée par la bibliothèque extrait le type en fonction de la valeur renvoyée par la méthode de résolveur. Cela signifie que vous devez renvoyer des instances de classe (vous ne pouvez pas renvoyer des objets JavaScript littéraux).

Pour fournir une fonction resolveType() personnalisée, passez la propriété resolveType à l’objet d’options passé au décorateur @InterfaceType(), comme suit :

Fonction resolveType personnalisée
@InterfaceType({
resolveType(book) {
if (book.colors) {
return ColoringBook;
}
return TextBook;
},
})
export abstract class Book {
@Field((type) => ID)
id: string;
@Field()
title: string;
}

Interface resolvers

Jusqu’à présent, en utilisant des interfaces, vous n’avez pu partager que des définitions de champs avec vos objets. Si vous souhaitez également partager l’implémentation réelle des résolveurs de champs, vous pouvez créer un résolveur d’interface dédié, comme suit :

Résolveur d'interface CharacterInterfaceResolver
import { Resolver, ResolveField, Parent, Info } from '@nestjs/graphql';
@Resolver((type) => Character) // Rappel : Character est une interface
export class CharacterInterfaceResolver {
@ResolveField(() => [Character])
friends(
@Parent() character, // Objet résolu qui implémente Character
@Info() { parentType }, // Type de l'objet qui implémente Character
@Args('search', { type: () => String }) searchTerm: string,
) {
// Obtenir les amis du personnage
return [];
}
}

Maintenant, le résolveur de champ friends est automatiquement enregistré pour tous les types d’objet qui mettent en œuvre l’interface Character.

Schema first

Pour définir une interface dans l’approche schema first, créez simplement une interface GraphQL avec SDL.

interface Character {
id: ID!
name: String!
}

Ensuite, vous pouvez utiliser la fonction de génération de typage (comme montré dans le chapitre quick start) pour générer des définitions TypeScript correspondantes :

Définition de l'interface Character en TypeScript
export interface Character {
id: string;
name: string;
}

Les interfaces nécessitent un champ supplémentaire __resolveType dans la carte des résolveurs pour déterminer à quel type l’interface doit être résolue. Créons une classe CharactersResolver et définissons la méthode __resolveType :

Résolveur de Characters avec __resolveType
@Resolver('Character')
export class CharactersResolver {
@ResolveField()
__resolveType(value) {
if ('age' in value) {
return Person;
}
return null;
}
}