Comment construire une API GraphQL avec Nest.js ?
Dans cet article, vous apprendrez à construire une API GraphQL avec NestJS en tirant parti de son architecture propre et de la sécurité des types.
NestJS est un framework NodeJS qui aide les utilisateurs à créer des applications dorsales évolutives de niveau entreprise en offrant une sécurité de type et un modèle architectural strict.
GraphQL est un langage de requête pour les interfaces de programmation d’applications (API) largement utilisé comme alternative à REST en raison de sa rapidité et de sa stabilité, qu’il permet d’obtenir en répondant aux requêtes avec les données exactes qu’elles demandent. Cette fonctionnalité de GraphQL résout le problème de l’overfetching et de l’underfetching posé par REST.
Contents
- 1 Mise en place de l’environnement de développement
- 2 Création d’une entité
- 3 Création d’un type d’objet
- 4 Création d’un service
- 5 Création d’un résolveur
- 6 Tester votre API à l’aide de GraphQL Playground
- 7 Back4app et GraphQL
- 8 Conclusion
- 9 FAQ
- 10 Qu’est-ce que GraphQL ?
- 11 Qu’est-ce que Nest.JS ?
- 12 Comment créer une API GraphQL avec Nest.JS ?
Mise en place de l’environnement de développement
Si l’interface de programmation Nest.js n’est pas installée globalement sur votre système, exécutez la commande ci-dessous pour l’installer :
npm i -g @nestjs/cli
L’interface de programmation Nest.js contient plusieurs commandes qui vous aident à générer du code standard pour faciliter votre processus de développement.
Ensuite, créez le projet et générez les fichiers de démarrage nécessaires en exécutant la commande ci-dessous :
nest new graphql-api
Ensuite, exécutez la commande ci-dessous pour vous rendre dans le répertoire de votre projet :
cd graphql-api
Ensuite, installez les dépendances requises en exécutant la commande ci-dessous :
npm i @nestjs/graphql @nestjs/apollo graphql apollo-server-express
Les dépendances installées ci-dessus incluent :
nest/graphql
nestjs/apollo
graphql
apollo-server-express
Ensuite, installez le paquet TypeORM et le pilote de base de données sqlite en exécutant la commande ci-dessous :
npm install @nestjs/typeorm typeorm sqlite3
Vous aurez besoin des paquets installés ci-dessus pour vous connecter à une base de données, la lire et l’écrire.
Configuration de GraphQL dans Nest.js
Nest.js propose deux façons de créer une API GraphQL : l’approche code-first et l’approche schéma-first.
L’approche code-first se caractérise par l’utilisation de décorateurs et de classes TypeScript pour générer le schéma GraphQL correspondant.
L’approche “schéma d’abord” se caractérise par l’utilisation des fichiers SDL (Schema Definition Language) de GraphQL, tandis que Nest.js génère des définitions TypeScript à l’aide de classes ou d’interfaces basées sur le schéma GraphQL.
Ce tutoriel présentera l’utilisation de l’approche code-first pour éviter de passer d’un langage à l’autre.
Pour utiliser l’approche “code first”, accédez au fichier d’entrée de votre application, app.module.ts
, et importez GraphQLModule
de @nestjs/graphql
. Comme suit :
import { GraphQLModule } from '@nestjs/graphql';
Ensuite, dans votre tableau d’importations
, appelez la méthode forRoot
du module GraphQL
. Cette méthode prend un objet de configuration comme argument. Les options de configuration sont transmises par le pilote GraphQL sous-jacent (ce tutoriel présente l’utilisation du pilote Apollo). Définissez la propriété autoSchemaFile
dans l’objet de configuration à schema.gql
. Par exemple :
//app.module.ts
GraphQLModule.forRoot({ autoSchemaFile: 'schema.gql' }),
La propriété autoSchemaFile
est le chemin d’accès au fichier dans lequel votre schéma généré automatiquement sera stocké.
Connexion à une base de données
Pour connecter votre application à une base de données, naviguez vers votre fichier app.module.ts
et importez TypeOrmModule
depuis @nestjs/typeorm
.
Comme cela :
import { TypeOrmModule } from '@nestjs/typeorm';
Ensuite, ajoutez le bloc de code ci-dessous à votre tableau d’importations :
TypeOrmModule.forRoot({
type: 'sqlite',
database: ':memory:',
entities: ['dist/**/*.entity{.ts,.js}'],
synchronize: true,
}),
Le bloc de code ci-dessus crée une connexion entre votre application et une base de données Sqlite et partage cette connexion entre tous les modules de votre application.
Générer des ressources
Ensuite, créez un module pour organiser votre code en exécutant la commande ci-dessous :
nest g module blog
La commande ci-dessus génère un module de blog pour votre application.
Ensuite, exécutez la commande ci-dessous pour créer un service :
nest g service blog
Le bloc de code ci-dessus génère et enregistre un service dans votre application. Ce service contiendra et gérera toute la logique commerciale de votre application.
Ensuite, exécutez la commande ci-dessous pour créer un résolveur :
nest g resolver
Le bloc de code ci-dessus génère et enregistre un résolveur dans votre application. Un résolveur spécifie des instructions pour transformer les requêtes et les mutations GraphQL en données et renvoie la forme des données spécifiée dans un schéma de manière synchrone ou asynchrone.
Création d’une entité
Une entité est une collection de champs qui spécifie comment les données sont stockées dans une base de données.
Pour créer une entité, dans le dossier de votre module (blog), créez un fichier d’entité en suivant la convention .entity.ts
, par exemple, blog.entity.ts.
Dans votre fichier d’entité, importez la colonne
, l’entité
et la colonne primaire générée
de typeorm
. Comme suit :
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
Le décorateur Column
ajoute les champs qu’il annote en tant que colonnes dans une base de données. Le décorateur Entity
marque la classe qu’il annote en tant qu’entité. Le décorateur PrimaryGeneratedColumn
marque la propriété qu’il annote comme l’identifiant unique de votre table et la génère automatiquement.
Ensuite, créez et exportez une classe, Blog
. Annotez ensuite la classe avec le décorateur Entity
pour la marquer comme une entité. Voici ce qu’il faut faire :
@Entity()
export class Blog {}
Puisque ce tutoriel présente une API de blog, ajoutez une propriété id, title, body, author et date à votre classe. Annotez ensuite chacune de ces propriétés avec le décorateur Column
, à l’exception de la propriété id
. Annotez la propriété id
avec le décorateur PrimaryGeneratedColumn
.
Comme cela :
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class Blog {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@Column()
body: string;
@Column()
author: string;
@Column()
date: string;
}
Création d’un type d’objet
Un type d’objet est une définition de schéma GraphQL représentant l’objet avec lequel le client doit interagir. Par exemple, si vous créez une API de blog, vous devrez définir le schéma/entité de blog avec une classe TypeScript et annoter chaque champ avec les décorateurs appropriés.
Ensuite, dans votre fichier d’entité, importez le type Int
et les décorateurs Field
et ObjectType
de @nestjs/graphql
. Voici comment procéder :
import { Field, Int, ObjectType } from '@nestjs/graphql';
Le décorateur Field
marque une propriété de classe spécifique en tant que champ GraphQL. Seules les propriétés annotées avec ce décorateur seront définies dans le schéma. Il accepte comme arguments une fonction de type retour optionnelle et un objet de configuration.
Le type Int
est nécessaire pour lever toute ambiguïté potentielle entre les systèmes de types TypeScript et GraphQL. Il n’est requis que pour les propriétés ayant des valeurs numériques, qui peuvent être soit des entiers, soit des flottants.
Le décorateur ObjectType
marque une classe en tant que type GraphQL.
Ensuite, annotez votre classe Blog avec le décorateur ObjectType
pour la marquer comme un type GraphQL. Voici comment procéder :
@ObjectType()
export class Blog {}
Enfin, spécifiez les propriétés requises de votre type à l’intérieur de la classe et annotez chacune d’entre elles avec le décorateur Field
. En voici un exemple :
//blog.entity.ts
import { Field, Int, ObjectType } from '@nestjs/graphql';
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
@ObjectType()
export class Blog {
@PrimaryGeneratedColumn()
@Field((type) => Int)
id: number;
@Column()
@Field()
title: string;
@Column()
@Field()
body: string;
@Column()
@Field()
author: string;
@Column()
@Field()
date: string;
}
Votre type d’objet terminé devrait ressembler au bloc de code ci-dessus.
Notez que l’id
avec un type de nombre
dans le bloc de code ci-dessus a été explicitement spécifié comme un entier pour éviter toute ambiguïté entre les systèmes de type TypeScript et GraphQL.
Enfin, injectez votre entité dans votre application pour créer une couche d’accès entre votre application et votre base de données.
Pour ce faire, accédez à votre fichier blog.module.ts
, importez TypeOrmModule
depuis @nestjs/typeorm
, et importez votre entité Blog.
Ensuite, ajoutez le bloc de code ci-dessous au décorateur de votre module :
imports: [TypeOrmModule.forFeature([Blog])],
Le bloc de code ci-dessus crée un référentiel qui servira de couche d’accès entre votre application et la base de données.
Création d’un service
Naviguez vers votre fichier de service généré précédemment, blog.service.ts
, et importez InjectRepository
de @nestjs/typeorm
et votre type d’objet.
Comme cela :
import { InjectRepository } from '@nestjs/typeorm';
import { Blog } from './blog.entity';
Ensuite, ajoutez le bloc de code ci-dessous à votre classe BlogService
pour injecter votre référentiel :
constructor(
@InjectRepository(Blog)
private blogRepository: Repository<Blog>,
) {}
Ensuite, ajoutez le bloc de code ci-dessous à votre classe de service pour mettre en œuvre la logique de récupération de tous les blogs dans la base de données :
async getAll(): Promise<Blog[]> {
return await this.blogRepository.find();
}
Ensuite, vous devrez mettre en œuvre la logique d’ajout d’un nouveau blog à votre base de données, mais d’abord, vous devrez créer un type d’entrée.
Création d’un type d’entrée
Pour créer un type d’entrée pour vos mutations qui prennent des objets complexes, créez un dossier dtos
dans votre dossier blog
. Ensuite, dans votre dossier dtos
, créez un nouveau fichier, create-blog.input.ts.
Dans votre fichier create-blog.input.ts
, importez les décorateurs Field
et InputType
. Comme suit :
import { Field, InputType } from '@nestjs/graphql';
Le décorateur InputType
marque une classe en tant que type d’entrée GraphQL.
Ensuite, créez et exportez une classe, BlogInput
. Annotez ensuite la classe avec le décorateur InputType
. Voici comment procéder :
@InputType()
export class BlogInput {}
Enfin, ajoutez toutes les propriétés de blog nécessaires et annotez-les avec le décorateur Field.
Comme cela :
//create-blog.input.ts
import { Field, InputType } from '@nestjs/graphql';
@InputType()
export class BlogInput {
@Field()
id: number;
@Field()
title: string;
@Field()
body: string;
@Field()
author: string;
@Field()
date: string;
}
Votre type d’entrée terminé devrait ressembler au bloc de code ci-dessus.
Ensuite, importez votre type d’entrée dans votre fichier de service et ajoutez le bloc de code ci-dessous à votre classe de service pour mettre en œuvre la logique d’ajout d’un blog à la base de données :
async createBlog(blogInput: BlogInput): Promise<Blog> {
const newBlog = this.blogRepository.create(blogInput);
return this.blogRepository.save(newBlog);
}
Le type d’entrée est appliqué de la même manière qu’un objet de transfert de données Nest.js ordinaire, en tant que mécanisme de validation des données entrantes. Comme pour les dtos, vous pouvez également effectuer une validation supplémentaire sur les données à l’aide du package class-validator
.
Création d’un résolveur
Naviguez jusqu’au fichier Resolver généré précédemment, blog.resolver.ts
, et importez votre entité, votre type d’entrée et votre service. Voici comment procéder :
import { Blog } from './blog.entity';
import { BlogService } from './blog.service';
import { BlogInput } from './dto/create-blog.input';
Ensuite, ajoutez le bloc de code ci-dessous à votre classe Resolver pour injecter votre service dans votre résolveur :
constructor(private blogService: BlogService) {}
Ensuite, importez les décorateurs Args
, Mutation
et Query
de @nestjs/graphql
.
Comme cela :
import { Args, Mutation, Query } from '@nestjs/graphql';
Le décorateur Args
extrait l’objet arguments de la plateforme sous-jacente et remplit le paramètre décoré avec la valeur de tous les arguments ou d’un seul argument spécifié.
Le décorateur Mutation
spécifie un itinéraire en tant que mutation.
Le décorateur Query
spécifie un itinéraire sous la forme d’une requête.
Ensuite, passez la fonction ci-dessous dans le décorateur Resolver
pour spécifier le type d’objet :
(of) => Blog
Ensuite, ajoutez le bloc de code ci-dessous à votre classe Resolver pour résoudre la méthode getAll
.
@Query((type) => [Blog])
async getAllBlogs() {
return this.blogService.getAll();
}
Enfin, ajoutez le bloc de code ci-dessous à votre classe Resolver pour résoudre la méthode createBlog
.
@Mutation((returns) => Blog)
createBlog(@Args('blogInput') blogInput: BlogInput): Promise<Blog> {
return this.blogService.createBlog(blogInput);
}
Note : Veillez à spécifier le type de fonction de retour pour chaque décorateur.
Votre classe Resolver terminée devrait ressembler au bloc de code ci-dessous :
@Resolver((of) => Blog)
export class BlogResolver {
constructor(private blogService: BlogService) {}
@Query((type) => [Blog])
async getAllBlogs() {
return this.blogService.getAll();
}
@Mutation((returns) => Blog)
createBlog(@Args('blogInput') blogInput: BlogInput): Promise<Blog> {
return this.blogService.createBlog(blogInput);
}
}
Tester votre API à l’aide de GraphQL Playground
Pour tester votre application à l’aide du terrain de jeu GraphQL, disponible par défaut, exécutez la commande ci-dessous et naviguez jusqu’à http://localhost:3000/graphql.
npm start
Ensuite, vous devriez voir un terrain de jeu où vous pouvez tester vos requêtes et vos mutations, comme le montre l’image ci-dessous.
Pour récupérer tous les blogs de la base de données, exécutez la requête ci-dessous :
query getAll{
getAllBlogs {
id,
title,
body,
author,
date
}
}
Un exemple est présenté dans l’image ci-dessous :
Pour ajouter un blog à votre base de données, exécutez la mutation ci-dessous :
mutation createBlog {
createBlog (blogInput: {
id: 1,
title: "GraphQL is great",
body: "GraphQL APIs are faster than REST APIs",
author: "David Ekete",
date: "01-02-03"
}) {
id,
title,
body,
author,
date,
}
}
Un exemple est présenté dans l’image ci-dessous :
Back4app et GraphQL
En raison des nombreux avantages de GraphQL par rapport à REST, tels que le contrôle de l’extraction des données, la plateforme Back4app fournit une API GraphQL intégrée dans vos applications de parse fonctionnant sur la plateforme.
Cette intégration vous permet de vérifier la santé de votre serveur, d’effectuer des opérations de création, de lecture, de mise à jour et de suppression (CRUD) sur votre base de données, et bien plus encore, en écrivant de simples requêtes et mutations GraphQL.
Par exemple, pour vérifier l’état de santé de votre serveur backend à l’aide de l’API GraphQL, exécutez la requête ci-dessous :
query Health {
health
}
La requête ci-dessus renverra :
{
"data": {
"health": true
}
}
Pour commencer à utiliser la fonctionnalité GraphQL, naviguez vers votre tableau de bord Parse et sélectionnez et cliquez sur votre application. Dans l’interface utilisateur de votre application, sélectionnez et cliquez sur Core, puis sélectionnez et cliquez sur API console et choisissez la console GraphQL.
En suivant les instructions ci-dessus, vous ouvrirez une console GraphQL où vous pourrez exécuter vos requêtes et mutations similaires à l’espace de jeu GraphQL que vous avez utilisé dans le développement. Vous pouvez en savoir plus sur la fonctionnalité GraphQL de Back4app dans la documentation de Back4app.
Conclusion
Cet article explique comment créer une API GraphQL dans Nest.js et tester l’API avec le terrain de jeu GraphQL. Les API GraphQL présentent plusieurs avantages par rapport aux API REST.
Cependant, ils ne sont pas idéaux pour toutes les applications. Veillez à prendre en compte les avantages et les inconvénients de GraphQL et de REST avant de choisir celui qui convient le mieux à votre application.
Quel que soit votre choix, GraphQL ou REST, vous devrez toujours déployer votre application. Back4app est un BaaS low-code basé sur des technologies open-source qui simplifie votre processus de construction de backend en éliminant les tâches répétitives à l’aide de modèles réutilisables et en gérant la plupart de votre infrastructure backend.
Parmi les caractéristiques de Back4app, on trouve une base de données en temps réel, des fonctions cloud, des API et SDK natifs, un système complet de gestion des utilisateurs, et bien d’autres choses encore.
Cette plateforme propose également un volet gratuit qui vous permet d’explorer la plateforme sans payer de frais.
Bonne construction !
FAQ
Qu’est-ce que GraphQL ?
GraphQL est un langage open source de requête et de manipulation de données pour les API, créé par Facebook en 2012.
Qu’est-ce que Nest.JS ?
Nest.JS est un framework Node.js open source permettant de créer des applications côté serveur efficaces et évolutives.
Comment créer une API GraphQL avec Nest.JS ?
– Configurer GraphQL dans Nest.js
– Se connecter à une base de données
– Générer des ressources
– Créer une entité
– Créer un type d’objet
– Créer un service