~4 min de lecture
Mocker une API REST dans Angular avec JSON Server : tuto complet
Tu démarres un composant Angular qui doit afficher une liste, mais le backend n'est pas prêt. Tu peux soit attendre, soit mocker l'API en local et avancer sur ta vraie valeur ajoutée — l'UX et la logique métier.
json-server est l'option la plus rapide à mettre en place : un fichier db.json, une commande, et tu as un backend REST complet avec GET/POST/PUT/DELETE, filtres, pagination, et tri.
Voici le tuto complet, avec le troubleshooting et la comparaison aux alternatives.
TL;DR
pnpm add -D json-server concurrently- Créer un
db.jsonà la racine avec ton schéma - Ajouter trois scripts dans
package.json(start:angular,start:api,startqui lance les deux en parallèle) - Injecter
HttpClientdans un service et taperhttp://localhost:3000/clients - Pour des cas plus exigeants (auth, scénarios d'erreur scriptés) → bascule vers MSW
Pourquoi mocker (et pourquoi pas une API jetable hostée ?)
Les options pour bosser sans backend :
- JSONPlaceholder ou DummyJSON : zéro setup, mais schéma figé (tu ne peux pas modéliser tes propres entités).
json-server: tu contrôles ton schéma, tu écris en local, tu commitdb.jsonsi tu veux. Idéal pour le prototypage.- MSW (Mock Service Worker) : intercepte les requêtes côté browser via un Service Worker. Plus puissant pour scripter des scénarios.
- Mirage.js : full mock côté client avec ORM in-memory. Bon pour des tests E2E déterministes.
Pour démarrer ou prototyper une mini-app pédagogique, json-server gagne sur la simplicité. C'est ce qu'on utilise sur les modules d'EasyAngularKit.
Les commandes ci-dessous sont en
pnpm, mais tout fonctionne identiquement ennpmouyarn.
Étape 1 — Installer json-server dans ton projet Angular
pnpm add -D json-server concurrently
concurrently permet de lancer Angular et json-server dans le même terminal, avec un seul pnpm start. C'est le pattern qu'on a sur EAK.
Étape 2 — Créer un fichier db.json
Crée un fichier db.json à la racine :
{
"clients": [
{ "id": 1, "name": "Sophie", "email": "sophie@example.com" },
{ "id": 2, "name": "Yassine", "email": "yassine@example.com" }
]
}
Chaque clé du JSON devient une route REST complète :
GET /clients→ listeGET /clients/1→ détailPOST /clients→ création (auto-incrémenteid)PUT /clients/1→ remplacement completPATCH /clients/1→ mise à jour partielleDELETE /clients/1→ suppression
Et tu obtiens gratuitement filtres, pagination, tri : GET /clients?name_like=So&_page=1&_limit=10&_sort=name.
Étape 3 — Ajouter les scripts dans package.json
{
"scripts": {
"start:angular": "ng serve",
"start:api": "json-server --watch db.json --port 3000 --delay 200",
"start": "concurrently \"pnpm start:angular\" \"pnpm start:api\""
}
}
pnpm start lance Angular et le serveur JSON en parallèle. Le flag --delay 200 ajoute 200ms de latence pour simuler une vraie API — utile pour tester les états de chargement.
Étape 4 — Intégrer dans un service Angular
import { inject, Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
export interface Client {
id: number;
name: string;
email: string;
}
@Injectable({ providedIn: 'root' })
export class ClientService {
private readonly http = inject(HttpClient);
private readonly baseUrl = 'http://localhost:3000/clients';
list() {
return this.http.get<Client[]>(this.baseUrl);
}
create(client: Omit<Client, 'id'>) {
return this.http.post<Client>(this.baseUrl, client);
}
}
À condition d'avoir provideHttpClient() dans ta config root, tu peux maintenant consommer cette API comme un vrai backend.
Troubleshooting
"Failed to fetch" ou CORS error
json-server autorise CORS par défaut depuis n'importe quelle origine. Si tu vois une erreur CORS, vérifie :
- que ton script
start:apitourne bien (port 3000 occupé ?) - que ton service appelle
http://localhost:3000(pashttps://) - qu'aucun proxy Angular (
proxy.conf.json) n'intercepte la route différemment
Port 3000 déjà utilisé
# Trouver le process
lsof -i :3000
# Ou changer de port dans le script
"start:api": "json-server --watch db.json --port 3333"
Les modifications de db.json ne sont pas persistées
json-server écrit dans db.json uniquement sur les requêtes mutantes (POST/PUT/PATCH/DELETE) faites contre lui. Si tu modifies le fichier à la main pendant qu'il tourne, le watcher recharge et tu perds tes écritures côté API. Soit tu édites à la main et tu relances, soit tu passes par l'API.
Simuler des codes HTTP custom (401, 500)
json-server ne fait pas ça nativement. Deux options :
- Wrapper avec un middleware (
--middlewares routes.js) qui renvoie une réponse arbitraire selon la route - Bascule vers MSW qui gère ça nativement avec une syntaxe déclarative
Quand passer à MSW ou Mirage.js
json-server montre ses limites dès que tu as besoin de :
- Scénarios scriptés (la 3e requête renvoie 500, la 4e timeout) → MSW
- Tests E2E déterministes sans dépendance réseau → Mirage.js
- Auth flow avec tokens, expirations, refresh → MSW ou un backend léger (Express + JWT)
- Relations complexes entre entités (jointures, cascades) → Mirage.js (a un ORM interne)
Pour les modules d'EasyAngularKit, on reste sur json-server parce que c'est lisible pour quelqu'un qui débute. MSW est plus puissant mais aussi plus opaque (Service Worker dans l'onglet réseau).
Récap
| Besoin | Solution |
|---|---|
| Simuler un backend REST simple | json-server |
| Lancer Angular + API en même temps | concurrently + script start |
| Simuler des erreurs HTTP scriptées | MSW (Mock Service Worker) |
| Tests E2E déterministes | Mirage.js |
| Auth, JWT, refresh tokens | Backend léger (Express, Fastify) |
Pour aller plus loin sur l'architecture Angular et les services HTTP propres : 👉 EasyAngularKit — modules sur HttpClient, error handling et clean architecture.