L’un des facteurs les plus importants à prendre en compte lors de la conception d’une application est le type d’architecture API à utiliser. Une conception efficace de l’API est essentielle pour garantir la performance des applications tout au long de leur cycle de vie.


L’architecture RESTful est l’approche la plus populaire, mais elle présente un inconvénient majeur : une structure de point final fixe qui renvoie des données prédéterminées. Cette conception peut entraîner une communication inefficace.

En revanche, GraphQL, une alternative à REST, offre une plus grande flexibilité en vous permettant de ne demander que les données dont vous avez besoin.


Que sont les API GraphQL ?

GraphQL est un langage de requête que vous pouvez utiliser pour écrire des API (interfaces de programmation d’applications) dorsales. Contrairement aux API REST, qui disposent de plusieurs points d’accès à différentes données, les API GraphQL n’ont qu’un seul point d’entrée.

Lire  La taille du GPU affecte-t-elle les performances ? Explication des facteurs de forme des cartes graphiques

Les clients peuvent spécifier les données dont ils ont besoin dans leurs requêtes à partir de ce point d’entrée unique, ce qui les rend plus flexibles et plus efficaces pour récupérer uniquement les données nécessaires.

Illustration montrant deux serveurs web déployés dans un réseau.

En termes simples, une API GraphQL met en œuvre l’architecture GraphQL décrite dans les spécifications GraphQL. Cette conception implique la définition du schéma, des requêtes et des mutations avec lesquels les clients peuvent interagir.

Voici une décomposition simplifiée des composants essentiels de l’architecture de l’API GraphQL :

  1. Schéma : Un schéma est une description des types de données et d’opérations que l’API fournit. Fondamentalement, un schéma définit la structure des données disponibles et le type de requêtes et de mutations qu’un client peut exécuter pour modifier les données.
  2. Requêtes : Les clients utilisent des requêtes pour obtenir des données de la base de données en spécifiant la structure des données dont ils ont besoin. En outre, ils peuvent imbriquer plusieurs requêtes dans une seule demande HTTP afin d’obtenir des données connexes à partir de plusieurs points d’extrémité.
  3. Mutations : Les mutations sont des opérations utilisées pour modifier des données dans la base de données. Les clients peuvent envoyer des demandes de mutation pour créer, mettre à jour ou supprimer des données.

Configurer une base de données MongoDB

Pour commencer, créez une base de données MongoDB. Vous pouvez également mettre en place un cluster MongoDB dans le nuage gratuitement. Une fois votre base de données configurée, copiez la chaîne URI de connexion à la base de données de MongoDB.

Vous pouvez trouver le code de ce projet dans son dépôt GitHub.

Créer un serveur Apollo

Apollo Server est une implémentation de serveur GraphQL populaire qui vous permettra de construire des API GraphQL dans des environnements JavaScript, y compris Node.js, Express, et plus encore.

Créer un répertoire pour un nouveau projet et cd en elle :

 mkdir graphql-API-mongoDB
cd graphql-API-mongoDB

Ensuite, initialiser un nouveau projet Node.js.

 npm init --yes 

Cette commande crée un projet package.json fichier.

Installer les dépendances requises

Exécutez la commande suivante pour installer les paquets.

 npm install apollo-server graphql mongoose 

Enfin, créez un fichier index.js dans le répertoire racine de votre projet.

Configurer le serveur Apollo

Ouvrir index.js et ajoutez le code ci-dessous :

 const { ApolloServer } = require('apollo-server');
const mongoose = require('mongoose');
const typeDefs = require("./graphql/typeDefs");
const resolvers = require("./graphql/resolvers");

const server = new ApolloServer({
    typeDefs,
    resolvers
});

const MONGO_URI = 'mongodb://localhost:27017';

mongoose
  .connect(MONGO_URI, {
    useNewUrlParser: true,
    useUnifiedTopology: true,
  })
  .then(() => {
    console.log(`Db Connected`);
    return server.listen({ port: 5000 });
  })
  .then((res) => {
    console.log(`Server running at ${res.url}`);
  })
  .catch(err => {
    console.log(err.message);
  });

Ce code initialise un serveur GraphQL local à l’aide de la bibliothèque Apollo Server. Il établit ensuite une connexion à une base de données MongoDB avec l’URI de connexion donné.

Remarquez que le code transmet deux arguments à la nouvelle instance d’ApolloServer : typeDefs et resolvers. Ceux-ci spécifient les types de données et les opérations que l’API GraphQL peut exécuter.

Une fois la connexion à la base de données MongoDB établie, le serveur commence à écouter sur le port 5000.

Définir le modèle de données

Créez un nouveau dossier dans le répertoire racine de votre projet et nommez-le modèles. Dans ce dossier, créez un nouveau fichier nommé dataModel.js et y ajouter le code suivant :

 const {model, Schema} = require('mongoose');

const employeeSchema = new Schema({
    name: String,
    department: String,
    salary: String,
});

module.exports = model('Employee', employeeSchema);

Définir le schéma GraphQL

Un schéma GraphQL définit la structure des données que vous pouvez interroger à l’aide de l’API GraphQL. Le schéma décrit également les requêtes et les mutations que l’API peut exécuter. Vous pouvez utiliser des requêtes pour récupérer des données et des mutations pour les modifier.

Dans le répertoire racine de votre projet, créez un nouveau dossier et nommez-le graphql. A l’intérieur de ce dossier, ajoutez deux fichiers : typeDefs.js et resolvers.js

Ajouter le code ci-dessous dans le fichier typeDefs.js :

 const {gql} = require("apollo-server");

const typeDefs = gql`
  type Employee {
    id: ID!
    name: String
    department: String
    salary: String
  }
  input EmployeeInput {
    name: String
    department: String
    salary: String
  }
  type Query {
    getEmployee(id: ID): Employee #return Employee by id
    employees: [Employee] #return array of Employees
  }
  type Mutation {
    createEmployee(employeeInput: EmployeeInput): Employee
    updateEmployee(id: ID, employeeInput: EmployeeInput): Boolean
    deleteEmployee(id: ID): Boolean
  }
`;

module.exports = typeDefs;

Le code ci-dessus utilise l’élément gql fournie par le paquetage apollo-server pour créer un schéma GraphQL pour les données des employés.

Le schéma se compose de quatre éléments principaux : les types de données pour les informations sur les employés, les types d’entrée, les requêtes et les mutations que l’API peut effectuer.

Définir les résolveurs pour l’API GraphQL

Un résolveur est une fonction GraphQL qui définit les données à transmettre lorsqu’un client envoie une requête API pour récupérer des données. Essentiellement, son rôle principal est de récupérer les données requises à partir de la source de données spécifiée et de les renvoyer au client.

Ajoutez le code ci-dessous au fichier resolvers.js dans le fichier graphql . Les résolveurs, dans ce cas, sont spécifiés dans les objets Query et Mutation.

L’objet Query définit deux méthodes : employés et getEmployee. Ces méthodes sont chargées d’extraire les données relatives aux employés de la base de données à la demande d’un client.

 const Employee= require("../models/employeesModel");

// GraphQL Resolvers
const resolvers = {
  Query: {
    employees: async () => {
      try {
        const employees = await Employee.find({});
        return employees;
      } catch (error) {
        console.error(error);
        throw new Error('Failed to fetch employees');
      }
    },
    getEmployee: async (parent, args) => {
      try {
        const employee = await Employee.findById(args.id);
        return employee;
      } catch (error) {
        console.error(error);
        throw new Error('Failed to fetch employee by ID');
      }
    },
  },

L’objet Mutation possède trois méthodes : createEmployee, updateEmployeeet deleteEmployee. Ces méthodes modifient les données stockées dans la base de données MongoDB.

   Mutation: {
    async createEmployee (_, { employeeInput: { name, department, salary } }) {
      const newEmployee = new Employee({
        name: name,
        department: department,
        salary: salary
      });

      const response = await newEmployee.save();
      console.log(newEmployee);

      return {
        id: response._id,
        ...response._doc
      }
    },

    async updateEmployee (_, {id, employeeInput: {name, department, salary}}) {
      const updatedEmployee = await Employee.updateOne(
        { _id: id },
        { name, department, salary }
      );

      if (!updatedEmployee) {
        throw new Error(`Employee with ID: ${id} not found`);
      }

      return true; // Return a boolean value indicating update success
    },

    async deleteEmployee (_, {id}) {
      const deletedEmployee = await Employee.deleteOne({ _id: id });
        
      if (!deletedEmployee || deletedEmployee.deletedCount === 0) {
          throw new Error(`Employee with ID ${id} not found`);
      }

      return true; // Return a boolean value indicating deletion success
    },
 },
};

module.exports = resolvers;

Enfin, exécutez cette commande pour démarrer le serveur :

 node index.js 

Une fois la connexion à la base de données établie, le serveur démarrera sur le port 5000.

Vous pouvez tester la fonctionnalité de l’API GraphQL en effectuant des requêtes HTTP à partir du terrain de jeu GraphQL dans votre navigateur.

Par exemple, vous pouvez utiliser la fonction createEmployee mutation pour ajouter les données d’un nouvel employé dans la base de données MongoDB.

Implémentation de l'API GraphQL dans le navigateur à l'aide du client playground de GraphQL

Popularité de GraphQL dans la communauté des développeurs

GraphQL gagne en popularité dans la communauté des développeurs en tant qu’approche de conception d’API alternative à la populaire architecture REST.

Cela est dû à sa capacité à fournir un moyen plus souple et plus efficace d’extraire des données de diverses sources, à partir d’un seul point d’entrée. Cela évite d’avoir à gérer plusieurs points d’accès pour différentes données, ce qui est un problème courant avec l’architecture REST API. Cette solution de conception rationalise le processus de construction et de gestion des API dorsales.