Nouveau : Datasets open source gratuits disponibles !Decouvrir →
🔌
Intermediaire 25 min REST

Creer une API REST : bonnes pratiques

Créer une API REST : bonnes pratiques

Pourquoi créer une API REST : bonnes pratiques ?

Contexte réel : En tant que développeur, vous avez souvent besoin de partager des données entre différents systèmes ou applications. Une API REST est l'outil parfait pour ce faire car elle permet aux différentes parties d'une application de communiquer efficacement.

Un cas d'utilisation concret en 2-3 phrases : Imaginez une application mobile qui a besoin d'afficher les dernières actualités publiées sur un site web. En créant une API REST, le mobile peut simplement faire des appels HTTP pour récupérer les données nécessaires sans avoir à recharger l'application.

Prérequis

  • Connaissance de base du JavaScript et du développement web
  • Familiarité avec les concepts de backend (Node.js, Express)
  • Compétences en gestion de paquets (npm, yarn)
  • Brevet d'imagination et de motivation pour réaliser un projet complet

Outils à installer :

Concepts fondamentaux

1. Méthodes HTTP

La méthode HTTP détermine l'action à effectuer sur la ressource identifiée par le chemin d'accès.

GET : Récupère les données de la ressource.

// Exemple : GET /api/users
app.get('/api/users', (req, res) => {
  // Code pour récupérer et envoyer les utilisateurs
});

POST : Crée une nouvelle ressource.

// Exemple : POST /api/users
app.post('/api/users', (req, res) => {
  // Code pour créer un nouvel utilisateur
});

PUT : Met à jour une ressource existante.

// Exemple : PUT /api/users/1
app.put('/api/users/1', (req, res) => {
  // Code pour mettre à jour l'utilisateur avec id = 1
});

DELETE : Supprime une ressource existante.

// Exemple : DELETE /api/users/1
app.delete('/api/users/1', (req, res) => {
  // Code pour supprimer l'utilisateur avec id = 1
});

2. Structures de données

La structure des données détermine comment les données seront stockées et manipulées.

Modèle Objet Relational (MOR) :

// Exemple d'un modèle utilisateur en MongoDB
const UserSchema = new mongoose.Schema({
  name: String,
  email: String,
  password: String
});

const User = mongoose.model('User', UserSchema);

3. Contrôleurs et routes

Les contrôleurs gèrent les requêtes HTTP et renvoient une réponse.

Contrôleur de gestion des utilisateurs :

// Exemple d'un contrôleur pour la ressource /api/users
const UserController = {
  getUsers: async (req, res) => {
    try {
      const users = await User.find();
      res.status(200).json(users);
    } catch (error) {
      res.status(500).json({ error: 'Erreur lors de la récupération des utilisateurs' });
    }
  },
  
  createUser: async (req, res) => {
    try {
      const newUser = await User.create(req.body);
      res.status(201).json(newUser);
    } catch (error) {
      res.status(400).json({ error: 'Erreur lors de la création de l'utilisateur' });
    }
  }
};

module.exports = UserController;

Définition des routes :

// Exemple d'association des contrôleurs aux routes
app.get('/api/users', UserController.getUsers);
app.post('/api/users', UserController.createUser);

Mise en pratique : projet fil rouge

Étape 1 : Initialiser le projet

Créez un nouveau dossier pour votre projet et initialisez-le avec npm :

mkdir api-rest-todo-list
cd api-rest-todo-list
npm init -y

Installation des dépendances :

npm install express mongoose body-parser cors

Étape 2 : Configurer le serveur

Créez un fichier server.js :

// server.js
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');

const app = express();
app.use(bodyParser.json());
app.use(cors());

// Import des contrôleurs et routes
const todoController = require('./controllers/todoController');
app.use('/api/todos', todoController);

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Serveur en cours sur le port ${PORT}`);
});

Étape 3 : Créer le modèle de données

Créez un fichier models/todo.js :

// models/todo.js
const mongoose = require('mongoose');

const TodoSchema = new mongoose.Schema({
  title: {
    type: String,
    required: true
  },
  description: String,
  completed: {
    type: Boolean,
    default: false
  }
});

module.exports = mongoose.model('Todo', TodoSchema);

Étape 4 : Créer le contrôleur

Créez un fichier controllers/todoController.js :

// controllers/todoController.js
const Todo = require('../models/todo');

exports.getTodos = async (req, res) => {
  try {
    const todos = await Todo.find();
    res.status(200).json(todos);
  } catch (error) {
    res.status(500).json({ error: 'Erreur lors de la récupération des tâches' });
  }
};

exports.createTodo = async (req, res) => {
  try {
    const newTodo = await Todo.create(req.body);
    res.status(201).json(newTodo);
  } catch (error) {
    res.status(400).json({ error: 'Erreur lors de la création de la tâche' });
  }
};

exports.updateTodo = async (req, res) => {
  try {
    const updatedTodo = await Todo.findByIdAndUpdate(req.params.id, req.body, { new: true });
    if (!updatedTodo) return res.status(404).json({ error: 'Tâche non trouvée' });
    res.status(200).json(updatedTodo);
  } catch (error) {
    res.status(500).json({ error: 'Erreur lors de la mise à jour de la tâche' });
  }
};

exports.deleteTodo = async (req, res) => {
  try {
    const deletedTodo = await Todo.findByIdAndDelete(req.params.id);
    if (!deletedTodo) return res.status(404).json({ error: 'Tâche non trouvée' });
    res.status(204).send();
  } catch (error) {
    res.status(500).json({ error: 'Erreur lors de la suppression de la tâche' });
  }
};

Étape 5 : Définir les routes

Ajoutez les routes dans server.js :

// server.js
const todoController = require('./controllers/todoController');
app.get('/api/todos', todoController.getTodos);
app.post('/api/todos', todoController.createTodo);
app.put('/api/todos/:id', todoController.updateTodo);
app.delete('/api/todos/:id', todoController.deleteTodo);

Étape 6 : Tester l'API

Lancez le serveur :

node server.js

Utilisez Postman ou curl pour tester les routes :

## GET /api/todos
curl -X GET http://localhost:3000/api/todos

## POST /api/todos
curl -X POST http://localhost:3000/api/todos -H "Content-Type: application/json" -d '{"title": "Tâche 1", "description": "Description de la tâche 1"}'

Erreurs fréquentes et debugging

1. TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array-like object. Received undefined

Code incorrect :

// db.js
const mongoose = require('mongoose');
mongoose.connect();

Code correct :

// db.js
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/todo-app', { useNewUrlParser: true, useUnifiedTopology: true });

2. SyntaxError: Unexpected token 'export'

Code incorrect :

// models/todo.js
module.exports = (mongoose) => {
  const TodoSchema = new mongoose.Schema({
    title: String,
    description: String
  });

  return mongoose.model('Todo', TodoSchema);
};

Code correct :

// models/todo.js
const mongoose = require('mongoose');

const TodoSchema = new mongoose.Schema({
  title: String,
  description: String
});

module.exports = mongoose.model('Todo', TodoSchema);

3. Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent

Code incorrect :

// controllers/todoController.js
exports.getTodos = async (req, res) => {
  try {
    const todos = await Todo.find();
    res.status(200).json(todos);
    res.status(500).json({ error: 'Erreur lors de la récupération des tâches' });
  } catch (error) {}
};

Code correct :

// controllers/todoController.js
exports.getTodos = async (req, res) => {
  try {
    const todos = await Todo.find();
    res.status(200).json(todos);
  } catch (error) {
    res.status(500).json({ error: 'Erreur lors de la récupération des tâches' });
  }
};

Pour aller plus loin

  1. Authentification et sécurité : Apprenez à sécuriser votre API en utilisant JWT (JSON Web Tokens).
  2. Documentation : Utilisez Swagger pour documenter votre API.
  3. Tests unitaires : Ajoutez des tests unitaires avec Jest pour s'assurer que chaque partie de votre application fonctionne correctement.

Défi pratique

Créez une API REST pour un gestionnaire de notes (notes, tâches à faire). Implémentez les routes pour créer, lire, mettre à jour et supprimer des notes. Assurez-vous que votre API est sécurisée avec JWT et qu'elle est bien documentée.

Besoin d'aide sur REST ?

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

Recevoir des conseils

Questions frequentes

Quelle est la différence entre GET, POST, PUT et DELETE dans une API REST?
GET est utilisé pour récupérer des données, POST pour créer de nouvelles ressources, PUT pour mettre à jour ou remplacer une ressource existante, et DELETE pour supprimer une ressource.
Comment gérer les erreurs dans une API REST?
Il est recommandé de retourner des codes d'état HTTP appropriés (404 pour non trouvé, 500 pour erreur interne, etc.) et un objet JSON décrivant l'erreur.
Quelles sont les bonnes pratiques pour la sécurité d'une API REST?
La sécurité implique d'utiliser HTTPS, de limiter les accès aux ressources sensibles, de vérifier et valider les entrées utilisateurs, et de mettre en œuvre des mesures de protection contre l'injection SQL et les attaques XSS.

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.