Engineering

Découvrez tous nos articles rédigés par
nos Product Engineers

Blog > Engineering > Article

hubvisory people

Comment créer une API Rest ?

Dans cet article rédigé par Charles, tu retrouveras toutes les étapes pour créer ta propre API Rest.
calendar
écrit le19 oct. 2022
user
parCharles
time
6minutes

Dans un article précédent, nous avons défini ce qu’était une API REST. Mais comment cela se traduit-il dans le code? Afin de voir cela, Hubvisory te propose d’en créer une ensemble en Javascript. Les pré-requis? Une compréhension basique de Javascript, Node JS, un IDE et un Terminal!

Généralités

Avant de se lancer dans la création d’une API Rest, il est important de définir sa structure, c’est-à-dire :

  • Déterminer la/les ressource(s) dont on aura besoin
  • Déterminer si on a besoin des quatre opérations CRUD (Create Read Update Delete)
  • Définir des points de terminaisons (Endpoint)
  • Documenter son API

Le dernier élément est très important, surtout si vous créez des API publiques, car il permet aux autres développeurs de comprendre votre API, d’avoir des exemples de requêtes et de réponses précises.

Par la suite, nous allons créer une API Rest.

Contexte

Nous souhaitons créer une API Rest permettant à des restaurateurs de :

  • Enregistrer des commandes des clients
  • Visualiser toutes les commandes
  • Modifier des commandes qui n’ont pas encore été réglé
  • Supprimer des commandes

Conception

Le contexte étant fixé, nous identifions la ressource “orders” pour les commandes. Nous pouvons donc définir nos points de terminaisons (URI) en sachant que d’après le contexte, nous aurons besoin de faire un CRUD :

  • GET/orders
  • POST/orders
  • PUT/orders/{orderID}
  • DELETE/orders/{orderID}

Réalisation

Dans un nouveau dossier, créez un fichier index.js dans lequel on va ajouter le code suivant :

// Charge le module HTTP
const http = require("http");
const host = "localhost";
const port = 8000;

//fonction qui renvoie les réponses du serveur 
const requestOrders = function (req, res) {
    res.writeHead(200);
    res.end("Hello world !!");
};

//crée l'objet server qui acceptera les requêtes HTTP 
const server = http.createServer(requestOrders);

//démarre le serveur sur le port renseigné
server.listen(port, host, () => {
  console.log(`Server is running on <http://$>{host}:${port}`);
});

Dans le terminal, tapez la commande node index.js qui permet de lancer le serveur. Vous devriez voir "Server is running on http://localhost:8000 " s’afficher dans le terminal.

Ouvrez un navigateur et tapez **http://localhost:8000 **: Hello world !! s’affiche. Notre serveur fonctionne bien.

Par la suite, nous utiliserons l’outil CLI curl dans une nouvelle fenêtre du terminal pour communiquer avec le serveur.

Avant de créer notre API, nous allons créer une constante contenant nos commandes. Ajoutez le code suivant dans le fichier index.js

...
let orders = JSON.stringify([
  {
    id: "OGCXnHRzZPjDIoPGyuutcMbx",
    total: 10,
    items: [
      {
        id: "6EqtxEG93VwrRLunr5uyXOJT",
        name: "Salade",
        price: 10,
      },
    ],
  },
  {
    id: "8DhLRD2M7NdzlqUYpDdLX7sb",
    total: 15,
    items: [
      {
        product: [
          {
            id: "jYKdRprTRAhK7GXsEwapaK6L",
            name: "Pâtes",
            price: 15,
          },
        ],
      },
    ],
  },
]);
...

Maintenant, passons à notre API Rest.

  • Méthode GET

Dans la fonction requestOrders() précédemment créée, supprimez res.end("Hello world !!") et ajoutez le code suivant :

...
switch ((req.url, req.method)) {
    case ("/orders", "GET"):
      res.writeHead(200);
      res.end(orders);
      break;
  }
...

Enregistrez et entrez la commande node index.js dans le terminal, puis dans un autre terminal, entrez la commande suivante :

curl -i -X GET [<http://localhost:8000>](<http://localhost:8000/>)/orders

**output**
[
    {
    id: "OGCXnHRzZPjDIoPGyuutcMbx",
    total: 10,
    items: [
      {
        id: "6EqtxEG93VwrRLunr5uyXOJT",
        name: "Salade",
        price: 10,
      },
    ],
  },
  {
    id: "8DhLRD2M7NdzlqUYpDdLX7sb",
    total: 15,
    items: [
      {
        product: [
          {
            id: "jYKdRprTRAhK7GXsEwapaK6L",
            name: "Pâtes",
            price: 15,
          },
        ],
      },
    ],
  }
]
  • Méthode POST

Dans la fonction requestOrders() , ajoutez le code suivant : (attention à bien déclarer la variable data)

...
case ("/orders", "POST"):
      req.on("data", (chunk) => {
        data += chunk;
      });
      req.on("end", () => {
        orders = JSON.stringify(JSON.parse(orders).concat(JSON.parse(data)));
        res.end(orders);
      });
      res.writeHead(200);
      break;
...

Enregistrez et relancez le serveur, puis dans un autre terminal, entrez la commande suivante :

curl -i -X POST -H 'Content-Type: application/json' -d '{"id": "Dw3ZTpjRK4UVHqC_S6DGqpGe","total": 6,"items": [{"id": "YuHopwCycWGapzKoxh-coL3o","name": "Coca","price": 6}]}' [<http://localhost:8000/orders>](<http://localhost:8000/orders>)  

**outpout**
[
    {
    id: "OGCXnHRzZPjDIoPGyuutcMbx",
    total: 10,
    items: [
      {
        id: "6EqtxEG93VwrRLunr5uyXOJT",
        name: "Salade",
        price: 10,
      },
    ],
  },
  {
    id: "8DhLRD2M7NdzlqUYpDdLX7sb",
    total: 15,
    items: [
      {
        product: [
          {
            id: "jYKdRprTRAhK7GXsEwapaK6L",
            name: "Pâtes",
            price: 15,
          },
        ],
      },
    ],
  },
    {
    id: "Dw3ZTpjRK4UVHqC_S6DGqpGe",
    total: 6,
    items: [
      {
        product: [
          {
            id: "YuHopwCycWGapzKoxh-coL3o",
            name: "Coca",
            price: 6,
          },
        ],
      },
    ],
  },
]
  • Méthode PUT

Dans la fonction requestOrders() , ajoutez le code suivant : (attention à bien déclarer la variable orderId)

...
case ("/orders/:id", "PUT"):
      orderId = req.url.split("/").pop();
      req.on("data", (chunk) => {
        data += chunk;
      });
      req.on("end", () => {
        orders = JSON.stringify(
          JSON.parse(orders).map((order) => {
            if (order.id === orderId) return JSON.parse(data);
            return order;
          })
        );
        res.end(orders);
      });
      res.writeHead(200);
      break;
...

Enregistrez et relancez le serveur, puis dans un autre terminal, entrez la commande suivante :

curl -i -X PUT -H 'Content-Type: application/json' -d '{"id": "8DhLRD2M7NdzlqUYpDdLX7sb","total": 14,"items": {"id": "DUyibRqzUHCd1kKvOD-wz28O","name": "Hamburger","price": 14}}' [<http://localhost:8000/orders>](<http://localhost:8000/orders>)/8DhLRD2M7NdzlqUYpDdLX7sb

**outpout**
[
    {
    id: "OGCXnHRzZPjDIoPGyuutcMbx",
    total: 10,
    items: [
      {
        id: "6EqtxEG93VwrRLunr5uyXOJT",
        name: "Salade",
        price: 10,
      },
    ],
  },
  {
    id: "8DhLRD2M7NdzlqUYpDdLX7sb",
    total: 14,
    items: [
      {
        product: [
          {
            id: "DUyibRqzUHCd1kKvOD",
            name: "Hamburger",
            price: 14,
          },
        ],
      },
    ],
  }
    
]
  • Méthode DELETE

Dans la fonction requestOrders() , ajoutez le code suivant :

...
case ("/orders/:id", "DELETE"):
      orderId = req.url.split("/").pop();
      orders = JSON.stringify(
        JSON.parse(orders).filter((order) => order.id !== orderId)
      );
      res.writeHead(200);
      res.end(orders);
      break;
...

Enregistrez et relancez le serveur, puis dans un autre terminal, entrez la commande suivante :

curl -i -X DELETE <http://localhost:8000/orders/8DhLRD2M7NdzlqUYpDdLX7sb>

**outpout**
[
    {
    id: "OGCXnHRzZPjDIoPGyuutcMbx",
    total: 10,
    items: [
      {
        id: "6EqtxEG93VwrRLunr5uyXOJT",
        name: "Salade",
        price: 10,
      },
    ],
  },
]

Voici à quoi devrait ressembler votre script final :

// Charge le module HTTP
const http = require("http");
const host = "localhost";
const port = 8000;

let orders = JSON.stringify([
  {
    id: "OGCXnHRzZPjDIoPGyuutcMbx",
    total: 10,
    items: [
      {
        id: "6EqtxEG93VwrRLunr5uyXOJT",
        name: "Salade",
        price: 10,
      },
    ],
  },
  {
    id: "8DhLRD2M7NdzlqUYpDdLX7sb",
    total: 15,
    items: [
      {
        product: [
          {
            id: "jYKdRprTRAhK7GXsEwapaK6L",
            name: "Pâtes",
            price: 15,
          },
        ],
      },
    ],
  },
]);

const requestOrders = function (req, res) {
  res.writeHead(200);
  let data = "";
  let orderId = "";
  switch ((req.url, req.method)) {
    // affiche la liste
        case ("/orders", "GET"):
      res.writeHead(200);
      res.end(orders);
      break;
        // ajouter un element dans la liste
    case ("/orders", "POST"):
      req.on("data", (chunk) => {
        data += chunk;
      });
      req.on("end", () => {
        orders = JSON.stringify(JSON.parse(orders).concat(JSON.parse(data)));
        res.end(orders);
      });
      res.writeHead(200);
      break;
        //modifier un element de la liste
    case ("/orders/:id", "PUT"):
      orderId = req.url.split("/").pop();
      req.on("data", (chunk) => {
        data += chunk;
      });
      req.on("end", () => {
        orders = JSON.stringify(
          JSON.parse(orders).map((order) => {
            if (order.id === orderId) return JSON.parse(data);
            return order;
          })
        );
        res.end(orders);
      });
      res.writeHead(200);
      break;
        //supprimer un element de la liste
    case ("/orders/:id", "DELETE"):
      orderId = req.url.split("/").pop();
      orders = JSON.stringify(
        JSON.parse(orders).filter((order) => order.id !== orderId)
      );
      res.writeHead(200);
      res.end(orders);
      break;
  }
};

//crée l'objet server qui acceptera les requêtes HTTP
const server = http.createServer(requestOrders);

//démarre le serveur sur le port renseigné
server.listen(port, host, () => {
  console.log(`Server is running on <http://$>{host}:${port}`);
});

Ceci n’étant qu’un script rudimentaire, voici certaines des évolutions qu’il est possible d’y ajouter :

  • Ajouter une method GET /orders/:id pour ne récupérer qu’un élément de la liste
  • Ajouter une method PATCH /orders/:id pour modifier une commande sans la surcharger complètement
  • Refactor le code afin de supprimer les utilisations redondantes de JSON.stringify() et JSON.parse()
  • Ecrire la donnée dans un fichier afin de la rendre persistante

Conclusion

Vous voilà à présent capable de créer une API Rest !

Vous remarquerez qu’il y a beaucoup d’élément redondants dans la création d’une API REST.

Heureusement, il existe de nombreux outils capables de simplifier ces démarches, comme Express ou NestJS.

Charles's photo
Article réalisé parCharles
category icon
Head of Dev Team
Charles linkedIn account link

Ces articles pourraient t'intéresser

article cover

Talk Source - La sécurité liée aux dépendances dans NodeJs

category icon
Engineering
article cover

What is a Product Team ?

category icon
Engineering
article cover

Retour sur mission : Gaël et Corentin parlent d'Adeo

category icon
Engineering
contact us logo

Tu as envie de parler produit avec nous ?

Tu souhaites nous poser des questions sur un sujet ou tout simplement en proposer un ? N’hésites pas !

Nous contacter