Nouveau : Datasets open source gratuits disponibles !Decouvrir →
🟢
Intermediaire 30 min NestJS

NestJS avec GraphQL

Pourquoi NestJS avec GraphQL ?

Contexte réel : GraphQL est une alternative puissante aux API REST, offrant un contrôle total sur les données requises et renvoyées par l'API. Un dev a besoin de ce type d'infrastructure au quotidien pour construire des applications rapides, scalables et efficaces.

Un cas d'utilisation concret : Lorsqu'un développeur crée une application web monopage (SPA) qui nécessite des données complexes provenant de plusieurs sources API, GraphQL permet de récupérer exactement les données nécessaires en un seul appel. Par exemple, dans une application e-commerce, au lieu de faire plusieurs requêtes pour obtenir les informations du produit, des revues, des catégories et des prix, on peut utiliser GraphQL pour récupérer toutes ces données en un seul appel.

Prerequis

  • Connaissances Necessaires :

    • Connaissance de base de Node.js et JavaScript ES6.
    • Familiarité avec les concepts de TypeScript.
    • Un certain niveau d'expertise avec les frameworks Angular, React ou Vue.js pour mieux comprendre la façon dont GraphQL peut être intégré à ces technologies.
  • Outils à Installer :

    • Node.js (>=12.x)
    • npm (Node Package Manager) ou yarn
    • Visual Studio Code (VSCode)

Concepts fondamentaux

Schema et Types de Données

GraphQL utilise un langage de schéma pour décrire les données que l'API peut renvoyer. Cela définit la structure exacte des requêtes et réponses possibles.

Exemple :

type Query {
  hello: String
}

schema {
  query: Query
}

Resolvers

Les résolveurs sont des fonctions qui définissent comment récupérer les données pour une requête particulière. Ils sont liés aux champs du schéma et déterminent la logique métier à exécuter.

Exemple :

import { Resolver, Query } from '@nestjs/graphql';

@Resolver()
export class AppResolver {
  @Query(() => String)
  hello(): string {
    return 'Hello World!';
  }
}

Mutations

Les mutations sont utilisées pour modifier les données de l'API. Elles ressemblent aux requêtes mais permettent également des modifications.

Exemple :

type Mutation {
  createTask(title: String!): Task
}

type Task {
  id: ID!
  title: String!
}

Subscriptions

Les souscriptions sont utilisées pour envoyer des notifications en temps réel à l'client. Cela permet aux clients de recevoir des mises à jour instantanées dès qu'une certaine action est effectuée.

Exemple :

type Subscription {
  newTask: Task
}

type Task {
  id: ID!
  title: String!
}

Mise en pratique : Projet fil rouge

Nous allons créer une application simple pour gérer les tâches à faire avec GraphQL et NestJS. Cette application comprendra des opérations de création, lecture, mise à jour et suppression de tâches.

Étape 1 : Initialiser le projet

nest new task-manager
cd task-manager
npm install @nestjs/graphql graphql-tools graphql apollo-server-express

Étape 2 : Créer les types et résolveurs

Créez un fichier task.model.ts :

export class Task {
  id: string;
  title: string;
  completed: boolean;
}

Créez un fichier app.resolver.ts :

import { Resolver, Query, Mutation, Arg } from '@nestjs/graphql';
import { Task } from './task.model';

let tasks: Task[] = [];

@Resolver()
export class AppResolver {
  @Query(() => [Task])
  async findAllTasks(): Promise<Task[]> {
    return tasks;
  }

  @Mutation(() => Task)
  async createTask(@Arg('title') title: string): Promise<Task> {
    const task = { id: Date.now().toString(), title, completed: false };
    tasks.push(task);
    return task;
  }

  @Mutation(() => Task)
  async updateTask(
    @Arg('id') id: string,
    @Arg('title', { nullable: true }) title?: string,
    @Arg('completed', { nullable: true }) completed?: boolean
  ): Promise<Task> {
    const task = tasks.find(t => t.id === id);
    if (task) {
      if (title !== undefined) task.title = title;
      if (completed !== undefined) task.completed = completed;
    }
    return task;
  }

  @Mutation(() => Task)
  async deleteTask(@Arg('id') id: string): Promise<Task> {
    const index = tasks.findIndex(t => t.id === id);
    if (index !== -1) {
      const task = tasks.splice(index, 1)[0];
      return task;
    }
    throw new Error(`Task with id ${id} not found`);
  }
}

Étape 3 : Configurer le serveur GraphQL

Modifier app.module.ts :

import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { join } from 'path';

@Module({
  imports: [
    GraphQLModule.forRoot({
      autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
      sortSchema: true,
      playground: true,
    }),
  ],
  controllers: [],
  providers: [],
})
export class AppModule {}

Étape 4 : Exécuter l'application

npm run start

Accédez à http://localhost:3000/graphql et essayez les requêtes suivantes :

  • Requête pour obtenir toutes les tâches :
query {
  findAllTasks {
    id
    title
    completed
  }
}
  • Mutation pour créer une nouvelle tâche :
mutation {
  createTask(title: "Buy groceries") {
    id
    title
    completed
  }
}

Erreurs fréquentes et debugging

Erreur 1 : Cannot query field "findAllTasks" on type "Query"

Cause : Le nom de la fonction du résolveur n'est pas correctement associée au champ dans le schéma.

Correction :

@Resolver()
export class AppResolver {
  @Query(() => [Task], { name: 'findAllTasks' })
  async findAllTasks(): Promise<Task[]> {
    return tasks;
  }
}

Erreur 2 : Type 'Promise<Task[]>' is not assignable to type 'Task[]'

Cause : La fonction de résolution renvoie une promesse, mais le schéma attend un tableau direct.

Correction :

@Query(() => [Task])
async findAllTasks(): Promise<Task[]> {
  return tasks;
}

Erreur 3 : Cannot resolve field "completed" on type "Task"

Cause : Le champ completed n'est pas défini dans le schéma.

Correction :

type Task {
  id: ID!
  title: String!
  completed: Boolean!
}

Pour aller plus loin

Piste 1 : Intégrer les souscriptions

Ajoutez des mutations et des souscriptions pour permettre la création instantanée de nouvelles tâches.

Piste 2 : Optimiser le chargement des données

Utilisez le système de résolution asynchrone GraphQL pour charger uniquement les données nécessaires.

Piste 3 : Authentification et autorisation

Ajoutez une couche d'authentification et d'autorisation à votre API pour protéger vos données sensibles.

Défi pratique

Créez un mini-projet réel qui implémente une application de gestion des utilisateurs avec des opérations CRUD. Incluez des fonctionnalités comme la création d'utilisateurs, l'affichage des informations utilisateur et la mise à jour des profils. Utilisez GraphQL pour récupérer uniquement les données nécessaires en un seul appel.

Besoin d'aide sur NestJS ?

Besoin d'aide sur un projet technique ? Decrivez-le pour des conseils personnalises.

Recevoir des conseils

Questions frequentes

Quelle est la différence entre NestJS et Express.js ?
NestJS est un cadre basé sur TypeScript qui utilise le design pattern MVC (Modèle-Vue-Contrôleur), tandis que Express.js est une bibliothèque middleware Node.js plus lightweight. NestJS offre des fonctionnalités avancées telles que l'injection de dépendances, les pipes, et la validation automatique.
Comment installer GraphQL dans un projet NestJS ?
Pour installer GraphQL dans un projet NestJS, vous pouvez utiliser le CLI NestJS avec la commande `nest generate graphql`. Cela installera les dépendances nécessaires et configurera un schéma de base pour votre application GraphQL.
Quelle est l'utilité des résolveurs en GraphQL avec NestJS ?
Les résolveurs en GraphQL sont des fonctions qui définissent comment récupérer les données requises pour chaque champ du schéma. En NestJS, vous pouvez créer des résolveurs grâce à des décorateurs spécifiques et en utilisant la syntaxe TypeScript, facilitant ainsi le développement de votre application.

Pages liees

Chaque semaine, le meilleur de la tech francaise

Tendances, salaires, outils et opportunites — directement dans votre boite mail.

Gratuit. Desabonnement en un clic. Pas de spam.