4. Qu'est-ce qu'une API ?
Une API (Application Programming Interface) est une interface qui permet à deux applications de communiquer entre elles via des règles et des conventions standardisées.
Analogie simple :
- Un restaurant : Vous consultez le menu (documentation API), passez commande au serveur (requête), et recevez votre plat (réponse)
- Le serveur = l'API
- La cuisine = le serveur backend
- Vous = le client (application web, mobile, etc.)
REST API : Les principes
REST (Representational State Transfer) est un style architectural pour concevoir des API web.
Les 6 principes REST
-
Architecture Client-Serveur
- Séparation entre interface utilisateur (client) et stockage de données (serveur)
-
Sans état (Stateless)
- Chaque requête contient toutes les informations nécessaires
- Le serveur ne garde pas de "session"
-
Cacheable
- Les réponses indiquent si elles peuvent être mises en cache
-
Interface uniforme
- URLs cohérentes et prévisibles
-
Système en couches
- Le client ne sait pas s'il parle directement au serveur ou à un intermédiaire
-
Code à la demande (optionnel)
- Le serveur peut envoyer du code exécutable (JavaScript)
HTTP
À chaque fois que vous tentez d'accéder à une page web vous réalisez une requête HTTP. Cette requête va contacter l'hébergeur de la page que vous ciblez et va attendre une réponse qui permettra l'affichage du site. Il est important de comprendre que lorsque vous cherchez à accéder à un site, pour chaque fichier requis vous réaliserez une requête HTTP pour obtenir l'information. Les gros sites pouvant rapidement atteindre des masses critiques de requêtes, il est important pour eux d'optimiser les appels HTTP au maximum afin de gagner en performances.

Types de requête
Lorsque vous réalisez une requête HTTP elle possède un type. Par défaut il s'agit d'une requête GET. Elle permet
d'obtenir des informations en les ramenant au client. Mais il existe de nombreux autres types, dont voici une liste des
plus fréquemment rencontrés.
GETpermet de récupérer des donnéesPOSTpermet de créer une ressourcePATCHpermet de modifier partiellement une ressourcePUTpermet de remplacer entièrement une ressourceDELETEpermet de supprimer une ressourceHEAD: permet de ne récupérer que les informations d'en-tête et donc de limiter la taille de la réponse. Utile lorsque l'on souhaite faire des vérifications avant une requête GET par exemple pour connaître la taille de la page en amont.
Sémantique des URL en REST
Dans une API REST, une URL ne décrit pas une action, mais une ressource.
La sémantique des URL est un élément fondamental : une API bien conçue doit pouvoir être comprise simplement en lisant ses
routes.
Une bonne règle à retenir est la suivante :
Une URL désigne une ressource, la méthode HTTP décrit l’action.
Une URL représente une ressource
Une ressource est une entité manipulée par l’API : utilisateur, article, commande, etc.
/users
/users/42
/orders/12
/usersreprésente la collection des utilisateurs/users/42représente un utilisateur spécifique/orders/12représente une commande précise
Les ressources sont généralement nommées au pluriel et de manière explicite.
Les actions sont portées par les méthodes HTTP
Il est important de ne pas mettre de verbes dans les URL.
Mauvaises pratiques
GET /getUsers
POST /createUser
POST /deleteUser/42
Bonnes pratiques
GET /users
POST /users
GET /users/42
DELETE /users/42
Hiérarchie et relations entre ressources
Les URL peuvent refléter des relations entre ressources.
/users/42/posts
/users/42/posts/3
/users/42/posts: tous les articles de l’utilisateur 42/users/42/posts/3: un article précis de l’utilisateur 42
Cette hiérarchie permet de rendre l’API plus lisible et plus intuitive.
Paramètres de chemin et paramètres de requête
Il est important de distinguer les paramètres de chemin et les paramètres de requête.
Paramètres de chemin (path parameters)
Ils identifient une ressource précise.
/users/42
Paramètres de requête (query parameters)
Ils servent à filtrer, trier ou paginer une collection.
/users?role=admin&page=2&limit=10
- Les paramètres de chemin identifient une ressource
- Les paramètres de requête modifient la manière de récupérer une collection
Cas particuliers : actions métier
Certaines actions métier ne correspondent pas directement à une opération CRUD classique (par exemple : activer un compte, valider une commande, réinitialiser un mot de passe).
Deux approches sont possibles :
1. Créer une sous-ressource métier
POST /users/42/activation
2. Modifier l’état de la ressource existante
PATCH /users/42
{
"status": "active"
}
Ces deux approches sont acceptables tant que la sémantique reste cohérente et explicite.
Exemple de routes REST cohérentes
GET /articles
GET /articles/10
POST /articles
PATCH /articles/10
DELETE /articles/10
Ces routes permettent de comprendre immédiatement :
- quelles ressources sont manipulées
- quelles actions sont possibles
- comment l’API est structurée
À retenir
- Une URL représente une ressource, pas une action
- Les verbes doivent être portés par la méthode HTTP
- Les ressources sont nommées de manière claire et cohérente
- Une API REST bien conçue est lisible sans documentation
Codes HTTP
Une fois la réponse reçue, elle est souvent accompagnée d'un code qui permet de rapidement savoir la nature de la
réponse. Vous connaissez sûrement l'un des plus connus : le code 404 Not Found. Les codes HTTP se décomposent d'abord
avec leur chiffre de centaine qui correspond chacun à un type. Par exemple, le 4 de 400 ici correspond à une erreur
client. Et ensuite, on incrémente un nombre pour avoir du détail, ici 04 pour dire ressource non trouvée (not found).
| Code | Signification | Description |
|---|---|---|
| 200 | OK | La requête a été traitée avec succès. Cela signifie généralement que la requête a réussi et que la réponse contient les données demandées. |
| 201 | Created | La requête a été traitée avec succès, et une nouvelle ressource a été créée. Ceci est couramment utilisé pour les requêtes POST. |
| 204 | No Content | La requête a réussi, mais il n'y a pas de contenu à renvoyer. Par exemple, après une suppression (DELETE), la réponse peut être vide. |
| 400 | Bad Request | La requête est mal formulée ou manque d'informations nécessaires. Ce code indique généralement une erreur du côté du client. |
| 401 | Unauthorized | La requête nécessite une authentification. Ce code est souvent renvoyé lorsqu'une API requiert une clé d'API ou un jeton d'authentification. |
| 403 | Forbidden | Le serveur comprend la requête, mais il refuse de l'exécuter. Cela peut être dû à des permissions insuffisantes. |
| 404 | Not Found | La ressource demandée n'a pas été trouvée sur le serveur. Cela est couramment utilisé pour indiquer que l'URL ou l'endpoint n'existe pas. |
| 405 | Method Not Allowed | La méthode HTTP utilisée (par exemple, GET, POST, PUT, DELETE) n'est pas autorisée pour la ressource spécifiée. |
| 500 | Internal Server Error | Il y a une erreur côté serveur. Cela signifie que quelque chose s'est mal passé, mais le serveur ne peut pas donner plus de détails. |
Vous trouverez le détail des codes HTTP ici.
Réaliser une requête HTTP en NodeJS
Le but d'une API Node.js est de pouvoir répondre à des requêtes HTTP. Pour ce faire, nous allons utiliser le package natif
de Node.js http. Ce package nous permet de créer un serveur HTTP et de répondre à des requêtes. Nous avons déjà vu
comment créer le serveur et l'écouter. Maintenant, j'aimerais qu'il soit capable de créer des réponses en fonction du type
de requête.
Ce package étant natif à Node.js, il n'est pas nécessaire de l'installer.
Pour ce faire, nous allons récupérer l'objet req qui est passé en paramètre de notre callback de création de serveur.
Cet objet contient de nombreuses informations sur la requête, dont la méthode utilisée. Nous allons donc vérifier la
méthode de la requête et renvoyer une réponse en fonction via l'objet res.
import http from 'http'
// Création du serveur HTTP
const server = http.createServer((req, res) => {
// Récupération de l'URL et de la méthode de la requête
const url = req.url
const method = req.method
// Gestion de la route /users
if (url === '/users' && method === 'GET') {
// Simulation d'une liste d'utilisateurs
res.writeHead(200, { 'Content-Type': 'application/json' })
res.end(
JSON.stringify([
{ id: 1, name: 'Alice', email: 'alice@example.com' },
{ id: 2, name: 'Bob', email: 'bob@example.com' },
]),
)
}
// Gestion de la route /users/:id pour obtenir un utilisateur spécifique
else if (url?.startsWith('/users/') && method === 'GET') {
const userId = url.split('/')[2]
res.writeHead(200, { 'Content-Type': 'application/json' })
res.end(
JSON.stringify({
id: parseInt(userId),
name: 'John Doe',
email: 'john@example.com',
}),
)
}
// Gestion de la route /users avec POST
else if (url === '/users' && method === 'POST') {
// Récupération du body de la requête
let payload = ''
req.on('data', (body) => {
payload += body.toString()
})
req.on('end', () => {
const userData = JSON.parse(payload)
res.writeHead(201, { 'Content-Type': 'application/json' })
res.end(
JSON.stringify({
message: 'Utilisateur créé',
id: 3,
name: userData.name,
email: userData.email,
}),
)
})
}
// Gestion de la route racine
else if (url === '/' && method === 'GET') {
res.writeHead(200, { 'Content-Type': 'text/plain' })
res.end('Bienvenue sur le serveur HTTP\n')
}
// Route non trouvée
else {
res.writeHead(404, { 'Content-Type': 'text/plain' })
res.end('Route non trouvée\n')
}
})
// Démarrage du serveur sur le port 3000
server.listen(3000, () => {
console.log("Serveur en cours d'écoute sur le port 3000...")
})
Note: Une fonction callback est une fonction qui est passée en argument à une autre fonction et qui est ensuite exécutée à un moment donné, généralement après que cette fonction ait terminé son traitement. En d'autres termes, c'est une fonction qui "attend" d'être appelée une fois qu'une tâche asynchrone (comme une requête HTTP ou une opération de lecture de fichier) est terminée.