ITSkillsCenter
Développement Web

API REST : comprendre et utiliser les API pour intégrer des services

5 دقائق للقراءة
API REST : comprendre et utiliser les API pour intégrer des services

Ce que vous saurez faire à la fin

  1. Comprendre les principes REST en 10 minutes
  2. Consommer une API publique depuis terminal, Postman, Node
  3. Gérer authentification, pagination, erreurs
  4. Construire un petit serveur REST Express en 20 lignes
  5. Tester et documenter votre API

Durée : 2 heures. Pré-requis : Node.js 20+, connaissance JSON.

Étape 1 — Vocabulaire REST

Ressource   : "client", "facture", "produit" (nom commun pluriel)
Endpoint    : URL associée, ex: /clients, /clients/42
Verbe HTTP  : action sur la ressource
  GET    lire
  POST   créer
  PUT    remplacer entièrement
  PATCH  modifier partiellement
  DELETE supprimer
Status code : réponse serveur (200 OK, 404 Not Found, 500 Error...)

Étape 2 — Tester une API publique avec curl

# API JSONPlaceholder (gratuite, pour tests)
curl https://jsonplaceholder.typicode.com/users/1

# Lire avec jq (parseur JSON)
curl -s https://jsonplaceholder.typicode.com/users/1 | jq .

# Créer
curl -X POST https://jsonplaceholder.typicode.com/posts \
  -H "Content-Type: application/json" \
  -d '{"title":"Mon post","body":"Contenu","userId":1}'

# Supprimer
curl -X DELETE https://jsonplaceholder.typicode.com/posts/1

Étape 3 — Postman pour les tests interactifs

  1. Téléchargez Postman (postman.com/downloads).
  2. Créez une collection « Test API ».
  3. Ajoutez une requête : GET https://jsonplaceholder.typicode.com/users.
  4. Onglet Headers : ajoutez Accept: application/json si besoin.
  5. Send : vous voyez la réponse, status code, temps, taille.
  6. Sauvegardez comme « List users ».
  7. Dupliquez pour GET/POST/PUT/DELETE. Votre collection devient un cahier de tests.

Étape 4 — Client JavaScript avec fetch

const API = "https://jsonplaceholder.typicode.com";

async function getUser(id) {
  const r = await fetch(`${API}/users/${id}`);
  if (!r.ok) throw new Error(`HTTP ${r.status}`);
  return r.json();
}

async function creerPost(data) {
  const r = await fetch(`${API}/posts`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(data),
  });
  return r.json();
}

// Utilisation
const user = await getUser(1);
console.log(user.name);

const post = await creerPost({ title: "Salut", body: "Test", userId: 1 });
console.log(post.id);

Étape 5 — Gérer l’authentification

// Token dans le header Authorization
const TOKEN = process.env.API_TOKEN;

async function getFactures() {
  const r = await fetch("https://api.example.sn/v1/factures", {
    headers: { "Authorization": `Bearer ${TOKEN}` },
  });
  if (r.status === 401) throw new Error("Token invalide");
  if (!r.ok) throw new Error(`HTTP ${r.status}`);
  return r.json();
}
# Avec curl
curl -s "https://api.example.sn/v1/factures" \
  -H "Authorization: Bearer $TOKEN" \
  | jq '.data[] | {numero, montant}'

Étape 6 — Pagination

async function* paginerTous(url) {
  let next = url;
  while (next) {
    const r = await fetch(next).then(r => r.json());
    yield* r.data;
    next = r.links?.next;
  }
}

// Usage
for await (const client of paginerTous("https://api.example.sn/v1/clients?limit=100")) {
  console.log(client.nom);
}

Étape 7 — Retries et backoff

async function withRetry(fn, max = 3) {
  for (let i = 0; i < max; i++) {
    try {
      return await fn();
    } catch (e) {
      if (e.status === 429 || (e.status >= 500 && e.status < 600)) {
        const backoff = 2 ** i * 500 + Math.random() * 300;
        await new Promise(r => setTimeout(r, backoff));
        continue;
      }
      throw e;
    }
  }
  throw new Error("Max retries dépassé");
}

const data = await withRetry(() => getFactures());

Étape 8 — Idempotence pour POSTs critiques

import { randomUUID } from "crypto";

await fetch("https://api.example.sn/v1/paiements", {
  method: "POST",
  headers: {
    "Idempotency-Key": randomUUID(),   // unique par paiement
    "Content-Type": "application/json",
    "Authorization": `Bearer ${TOKEN}`,
  },
  body: JSON.stringify({ montant: 150000, client_id: 42 }),
});

Étape 9 — Construire votre première API avec Express

mkdir mon-api && cd mon-api
npm init -y
npm install express
// server.js
import express from "express";
const app = express();
app.use(express.json());

const clients = new Map();
let seq = 1;

// Créer
app.post("/v1/clients", (req, res) => {
  if (!req.body.nom) return res.status(400).json({ error: "nom requis" });
  const id = String(seq++);
  const c = { id, nom: req.body.nom, ville: req.body.ville || "" };
  clients.set(id, c);
  res.status(201).location(`/v1/clients/${id}`).json(c);
});

// Lister
app.get("/v1/clients", (_req, res) => {
  res.json({ data: [...clients.values()] });
});

// Lire un
app.get("/v1/clients/:id", (req, res) => {
  const c = clients.get(req.params.id);
  return c ? res.json(c) : res.status(404).json({ error: "not_found" });
});

// Modifier
app.patch("/v1/clients/:id", (req, res) => {
  const c = clients.get(req.params.id);
  if (!c) return res.status(404).json({ error: "not_found" });
  Object.assign(c, req.body);
  res.json(c);
});

// Supprimer
app.delete("/v1/clients/:id", (req, res) => {
  clients.delete(req.params.id);
  res.status(204).end();
});

app.listen(3000, () => console.log("API http://localhost:3000"));
node server.js
# Tester:
curl -X POST http://localhost:3000/v1/clients \
  -H "Content-Type: application/json" \
  -d '{"nom":"SARL Dakar","ville":"Dakar"}'

curl http://localhost:3000/v1/clients

Étape 10 — Validation avec Zod

npm install zod
import { z } from "zod";

const CreerClient = z.object({
  nom: z.string().min(2).max(100),
  ville: z.string().optional(),
  email: z.string().email().optional(),
});

app.post("/v1/clients", (req, res) => {
  const result = CreerClient.safeParse(req.body);
  if (!result.success) {
    return res.status(422).json({ errors: result.error.errors });
  }
  // ... use result.data
});

Étape 11 — CORS

npm install cors
import cors from "cors";

app.use(cors({
  origin: ["https://app.example.sn"],
  credentials: true,
}));

Étape 12 — Rate limiting

npm install express-rate-limit
import { rateLimit } from "express-rate-limit";

app.use("/v1/", rateLimit({
  windowMs: 60_000,
  max: 120,
  standardHeaders: true,
  legacyHeaders: false,
}));

Étape 13 — Tests avec Supertest

npm install -D supertest vitest
// server.test.js
import request from "supertest";
import app from "./server.js";

test("POST /v1/clients crée un client", async () => {
  const r = await request(app)
    .post("/v1/clients")
    .send({ nom: "Test" })
    .expect(201);
  expect(r.body).toHaveProperty("id");
});

test("GET /v1/clients/:id inexistant renvoie 404", async () => {
  await request(app).get("/v1/clients/9999").expect(404);
});

Étape 14 — Documenter avec OpenAPI

npm install swagger-ui-express swagger-jsdoc
import swaggerUi from "swagger-ui-express";
import swaggerJsdoc from "swagger-jsdoc";

const swaggerSpec = swaggerJsdoc({
  definition: {
    openapi: "3.0.0",
    info: { title: "Mon API", version: "1.0.0" },
  },
  apis: ["./server.js"],   // lit les commentaires JSDoc
});

app.use("/docs", swaggerUi.serve, swaggerUi.setup(swaggerSpec));
// Ouvrez http://localhost:3000/docs

Étape 15 — Checklist

✓ Noms de ressources au pluriel
✓ Verbes HTTP cohérents
✓ Codes retour standards (201, 204, 404, 422)
✓ Validation Zod sur toutes les entrées
✓ CORS configuré correctement
✓ Rate limiting en place
✓ Authentification Bearer token
✓ Idempotency-Key sur opérations critiques
✓ Retries + backoff côté client
✓ Tests Supertest pour chaque endpoint
✓ Documentation Swagger/OpenAPI exposée
Besoin d'un site web ?

Confiez-nous la Création de Votre Site Web

Site vitrine, e-commerce ou application web — nous transformons votre vision en réalité digitale. Accompagnement personnalisé de A à Z.

À partir de 250.000 FCFA
Parlons de Votre Projet
Publicité