🔌 Les API REST avec PHP
Créez des API REST performantes et professionnelles pour vos applications web
Qu'est-ce qu'une API REST ?
Définition
API REST (Representational State Transfer) est un style d'architecture pour créer des services web qui permet aux applications de communiquer entre elles via le protocole HTTP.
Imaginez que vous avez créé une application web qui gère une bibliothèque. Vous voulez maintenant créer une application mobile qui utilise les mêmes données. Au lieu de recréer toute la logique, vous créez une API REST qui agit comme un pont entre votre base de données et n'importe quelle application.
Architecture Client-Serveur
Pourquoi utiliser une API REST ?
- Séparation des préoccupations : Le frontend et le backend sont indépendants
- Réutilisabilité : Une même API peut servir une app web, mobile, IoT, etc.
- Scalabilité : Plus facile de faire évoluer l'application
- Standardisation : Utilise les conventions HTTP que tout le monde connaît
Les 6 principes REST
Client-Serveur
Séparation claire entre le client (interface) et le serveur (logique métier)
Sans état (Stateless)
Chaque requête contient toutes les informations nécessaires. Le serveur ne conserve pas l'état du client.
Cacheable
Les réponses peuvent être mises en cache pour améliorer les performances
Interface uniforme
Utilisation cohérente des méthodes HTTP et des URLs
Système en couches
Architecture modulaire avec différentes couches (routeur, contrôleur, modèle)
Code à la demande
Optionnel : Le serveur peut envoyer du code exécutable (JavaScript)
Les méthodes HTTP (Verbes)
Les API REST utilisent les méthodes HTTP pour définir le type d'action à effectuer :
Récupérer des données
Lecture d'une ou plusieurs ressources. Ne modifie pas les données.
GET /api/livre → Tous les livresGET /api/livre/5 → Livre avec ID 5
Créer une ressource
Ajout d'une nouvelle ressource dans la base de données.
POST /api/livre → Créer un nouveau livre
Modifier complètement
Remplacement complet d'une ressource existante.
PUT /api/livre/5 → Modifier le livre 5 (complet)
Modifier partiellement
Modification partielle d'une ressource existante.
PATCH /api/livre/5 → Modifier certains champs du livre 5
Supprimer une ressource
Suppression d'une ressource existante.
DELETE /api/livre/5 → Supprimer le livre 5
Convention CRUD
Les méthodes HTTP correspondent aux opérations CRUD :
- Create → POST
- Read → GET
- Update → PUT / PATCH
- Delete → DELETE
Query String vs Path Parameters
Il existe deux façons principales de passer des données dans une URL :
🛤️ Path Parameters (Paramètres de chemin)
Les données font partie du chemin de l'URL
GET /api/livre/5
GET /api/auteur/Jean-Dupont/livre
GET /api/categorie/fiction/livre/nouveautes
Utilisation
- Identifier une ressource spécifique
- Navigation hiérarchique
- Ressources imbriquées
/api/utilisateur/123/commandes/456→ Commande 456 de l'utilisateur 123
🔍 Query String (Chaîne de requête)
Les données sont ajoutées après le symbole ?
GET /api/livre?page=2&limit=10
GET /api/livre?auteur=Dupont&annee=2024
GET /api/livre?sort=titre&order=asc
Utilisation
- Filtrer les résultats
- Pagination
- Tri et recherche
- Options facultatives
/api/produit?categorie=electronique&prix_max=500→ Produits électroniques de moins de 500$
Syntaxe Query String
/api/ressource?param1=valeur1¶m2=valeur2¶m3=valeur3
?: Début de la query string=: Séparation nom/valeur&: Séparation entre paramètres
Quand utiliser l'un ou l'autre ?
| Critère | Path Parameters | Query String |
|---|---|---|
| Obligatoire | ✅ Oui, fait partie de la route | ❌ Non, paramètres optionnels |
| Identification | ✅ Identifier UNE ressource | ❌ Filtrer PLUSIEURS ressources |
| Hiérarchie | ✅ Relations parent/enfant | ❌ Pas de hiérarchie |
| Lisibilité | ✅ URLs plus propres | ⚠️ Peut devenir long |
Routes et Endpoints
Endpoint
Un endpoint est une URL spécifique qui expose une fonctionnalité de l'API. C'est le point d'entrée pour accéder à une ressource.
Conventions de nommage
/api/livre plutôt que /api/livre
/api/nouveau-livre plutôt que /api/nouveauLivre
GET /api/livre plutôt que GET /api/getLivre
/api/auteur/5/livre pour les livres de l'auteur 5
Exemple complet : API de bibliothèque
| Méthode | Endpoint | Description |
|---|---|---|
| GET | /api/livre
ivre
ivre |
Liste tous les livres |
| GET | /api/livre/{id} |
Détails d'un livre spécifique |
| POST | /api/livre |
Créer un nouveau livre |
| PUT | /api/livre/{id} |
Modifier complètement un livre |
| DELETE | /api/livre/{id} |
Supprimer un livre |
| GET | /api/auteur/{id}/livre |
Livres d'un auteur spécifique |
| GET | /api/categorie/{nom}/livre |
Livres d'une catégorie |
Travailler avec JSON en PHP
Avant de créer notre router, il est essentiel de comprendre comment PHP communique en JSON et comment configurer les en-têtes HTTP correctement.
Le header Content-Type
Le header Content-Type indique au client (navigateur, application mobile, etc.) quel type de données le serveur envoie. Pour une API REST, on utilise toujours application/json.
<?php
// ⚠️ IMPORTANT : À mettre au tout début de votre fichier PHP
// 1. Définir le type de contenu en JSON
header('Content-Type: application/json; charset=utf-8');
// 2. Autoriser les requêtes cross-origin (CORS)
header('Access-Control-Allow-Origin: *');
// 3. Autoriser les méthodes HTTP
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE');
// 4. Autoriser certains headers personnalisés
header('Access-Control-Allow-Headers: Content-Type, Authorization');
?>
Attention !
Les headers doivent être définis avant tout output (echo, print_r, etc.). Si vous affichez quelque chose avant, PHP ne pourra plus modifier les headers.
json_encode() : Convertir PHP → JSON
La fonction json_encode() transforme un tableau ou un objet PHP en chaîne JSON.
<?php
// Tableau associatif → Objet JSON
$livre = [
'id' => 1,
'titre' => 'Le Petit Prince',
'auteur' => 'Antoine de Saint-Exupéry',
'annee' => 1943,
'disponible' => true
];
echo json_encode($livre);
// Résultat : {"id":1,"titre":"Le Petit Prince","auteur":"Antoine de Saint-Exupéry","annee":1943,"disponible":true}
// Tableau indexé → Tableau JSON
$categories = ['Fiction', 'Science-Fiction', 'Philosophie'];
echo json_encode($categories);
// Résultat : ["Fiction","Science-Fiction","Philosophie"]
// Tableau de tableaux → Tableau d'objets JSON
$livres = [
['id' => 1, 'titre' => '1984'],
['id' => 2, 'titre' => 'Brave New World']
];
echo json_encode($livres);
// Résultat : [{"id":1,"titre":"1984"},{"id":2,"titre":"Brave New World"}]
// Options utiles
echo json_encode($livre, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
// JSON_UNESCAPED_UNICODE : Préserve les accents
// JSON_PRETTY_PRINT : Formate le JSON avec indentation
?>
Options courantes de json_encode()
| Option | Description |
|---|---|
JSON_PRETTY_PRINT |
Formate le JSON avec indentation (utile pour debug) |
JSON_UNESCAPED_UNICODE |
Garde les caractères Unicode (accents, émojis) tels quels |
JSON_UNESCAPED_SLASHES |
Ne pas échapper les slashes dans les URLs |
JSON_NUMERIC_CHECK |
Convertit les chaînes numériques en nombres |
Créer un Router en PHP
Un router est le composant qui analyse l'URL et la méthode HTTP pour déterminer quelle action exécuter.
Structure de base
<?php
// Configuration
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE');
// Récupérer la méthode HTTP
$method = $_SERVER['REQUEST_METHOD'];
// Récupérer l'URI et nettoyer
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$uri = trim($uri, '/');
// Diviser l'URI en segments
$segments = explode('/', $uri);
// Router simple
if ($segments[0] === 'api' && $segments[1] === 'livres') {
if ($method === 'GET' && !isset($segments[2])) {
// GET /api/livre - Liste tous les livres
getLivres();
} elseif ($method === 'GET' && isset($segments[2])) {
// GET /api/livre/{id} - Un livre spécifique
getLivre($segments[2]);
} elseif ($method === 'POST') {
// POST /api/livre - Créer un livre
createLivre();
} elseif ($method === 'PUT' && isset($segments[2])) {
// PUT /api/livre/{id} - Modifier un livre
updateLivre($segments[2]);
} elseif ($method === 'DELETE' && isset($segments[2])) {
// DELETE /api/livre/{id} - Supprimer un livre
deleteLivre($segments[2]);
} else {
http_response_code(404);
echo json_encode(['error' => 'Route non trouvée']);
}
} else {
http_response_code(404);
echo json_encode(['error' => 'Endpoint non trouvé']);
}
?>
Exemple avec .htaccess
Pour avoir des URLs propres, créez un fichier .htaccess :
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [L,QSA]
Que fait ce .htaccess ?
- Redirige toutes les requêtes vers
index.php - Sauf si le fichier ou dossier existe réellement
- Préserve les paramètres de query string (QSA)
Serveur PHP intégré (php -S)
Le serveur web interne de PHP ne supporte pas les fichiers .htaccess. Pour contourner ce problème, vous devez spécifier un fichier de routage :
# Au lieu de :
php -S localhost:8000
# Utilisez :
php -S localhost:8000 index.php
Ou créez un fichier router.php séparé :
<?php
// Fichier de routage pour le serveur PHP interne
if (php_sapi_name() === 'cli-server') {
// Si c'est un fichier réel, le servir tel quel
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$file = __DIR__ . $path;
if (is_file($file)) {
return false; // Servir le fichier statique
}
}
// Sinon, rediriger vers index.php
require __DIR__ . '/index.php';
# Démarrer le serveur avec le router :
php -S localhost:8000 router.php
Cette approche permet de conserver les fichiers statiques (CSS, JS, images) tout en redirigeant les requêtes API vers index.php.
Router orienté objet (POO)
<?php
class Router {
private $routes = [];
public function get($path, $callback) {
$this->addRoute('GET', $path, $callback);
}
public function post($path, $callback) {
$this->addRoute('POST', $path, $callback);
}
public function put($path, $callback) {
$this->addRoute('PUT', $path, $callback);
}
public function delete($path, $callback) {
$this->addRoute('DELETE', $path, $callback);
}
private function addRoute($method, $path, $callback) {
$this->routes[] = [
'method' => $method,
'path' => $path,
'callback' => $callback
];
}
public function run() {
$method = $_SERVER['REQUEST_METHOD'];
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
foreach ($this->routes as $route) {
$pattern = preg_replace('/\{[a-zA-Z]+\}/', '([^/]+)', $route['path']);
$pattern = '#^' . $pattern . '$#';
if ($route['method'] === $method && preg_match($pattern, $uri, $matches)) {
array_shift($matches); // Enlever le match complet
call_user_func_array($route['callback'], $matches);
return;
}
}
// Route non trouvée
http_response_code(404);
echo json_encode(['error' => 'Route non trouvée']);
}
}
// Utilisation
$router = new Router();
$router->get('/api/livre', function() {
// Logique pour récupérer tous les livres
});
$router->get('/api/livre/{id}', function($id) {
// Logique pour récupérer un livre spécifique
});
$router->post('/api/livre', function() {
// Logique pour créer un livre
});
$router->run();
?>
Structure des réponses JSON
JSON (JavaScript Object Notation) est le format standard pour les API REST.
Réponse réussie
{
"id": 5,
"titre": "Le Petit Prince",
"auteur": "Antoine de Saint-Exupéry",
"annee": 1943,
"isbn": "978-2-07-061275-8",
"disponible": true,
"prix": 12.99
}
Liste de ressources
{
"data": [
{
"id": 1,
"titre": "1984",
"auteur": "George Orwell",
"annee": 1949
},
{
"id": 2,
"titre": "Le Meilleur des mondes",
"auteur": "Aldous Huxley",
"annee": 1932
}
],
"pagination": {
"page": 1,
"limit": 2,
"total": 150,
"pages": 75
}
}
Créer une ressource
{
"success": true,
"message": "Livre créé avec succès",
"data": {
"id": 151,
"titre": "Nouveau livre",
"auteur": "Auteur Test",
"created_at": "2026-03-08T10:30:00Z"
}
}
Codes de statut HTTP
| Code | Status | Description | Utilisation |
|---|---|---|---|
| 200 | OK | Succès général | GET, PUT, PATCH réussis |
| 201 | Created | Ressource créée | POST réussi |
| 204 | No Content | Succès sans contenu | DELETE réussi |
| 400 | Bad Request | Requête invalide | Données manquantes/invalides |
| 401 | Unauthorized | Non authentifié | Pas de token/session |
| 403 | Forbidden | Accès refusé | Pas les permissions |
| 404 | Not Found | Ressource introuvable | ID n'existe pas |
| 500 | Internal Server Error | Erreur serveur | Bug, erreur PHP/SQL |
Gestion des erreurs
Une bonne API doit retourner des messages d'erreur clairs et cohérents.
Format standard d'erreur
{
"error": {
"code": 404,
"message": "Livre non trouvé",
"details": "Aucun livre ne correspond à l'ID 999"
}
}
{
"error": {
"code": 400,
"message": "Données de requête invalides",
"validation_errors": [
{
"field": "titre",
"message": "Le titre est obligatoire"
},
{
"field": "annee",
"message": "L'année doit être entre 1000 et 2026"
}
]
}
}
Classe PHP pour gérer les erreurs
<?php
class ErrorHandler {
public static function notFound($message = "Ressource non trouvée") {
http_response_code(404);
echo json_encode([
'error' => [
'code' => 404,
'message' => $message
]
]);
exit;
}
public static function badRequest($message, $validationErrors = []) {
http_response_code(400);
$error = [
'error' => [
'code' => 400,
'message' => $message
]
];
if (!empty($validationErrors)) {
$error['error']['validation_errors'] = $validationErrors;
}
echo json_encode($error);
exit;
}
public static function unauthorized($message = "Non authentifié") {
http_response_code(401);
echo json_encode([
'error' => [
'code' => 401,
'message' => $message
]
]);
exit;
}
public static function serverError($message = "Erreur interne du serveur") {
http_response_code(500);
echo json_encode([
'error' => [
'code' => 500,
'message' => $message
]
]);
exit;
}
}
// Utilisation
if (!$livre) {
ErrorHandler::notFound("Livre avec l'ID $id introuvable");
}
?>
Exemples pratiques complets
1. Endpoint GET - Liste des livres
<?php
// Connexion à la base de données
$host = 'localhost';
$dbname = 'bibliotheque';
$user = 'root';
$pass = '';
try {
$pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $user, $pass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
http_response_code(500);
echo json_encode(['error' => 'Erreur de connexion à la base de données']);
exit;
}
// Récupérer les paramètres de query string
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$limit = isset($_GET['limit']) ? (int)$_GET['limit'] : 10;
$search = isset($_GET['search']) ? $_GET['search'] : '';
// Calculer l'offset
$offset = ($page - 1) * $limit;
// Construire la requête SQL
$sql = "SELECT * FROM livre WHERE 1=1";
$params = [];
if (!empty($search)) {
$sql .= " AND (titre LIKE :search OR auteur LIKE :search)";
$params[':search'] = "%$search%";
}
// Compter le nombre total de résultats
$countSql = str_replace('*', 'COUNT(*) as total', $sql);
$countStmt = $pdo->prepare($countSql);
$countStmt->execute($params);
$total = $countStmt->fetch(PDO::FETCH_ASSOC)['total'];
// Ajouter la pagination
$sql .= " LIMIT :limit OFFSET :offset";
$stmt = $pdo->prepare($sql);
// Lier les paramètres
foreach ($params as $key => $value) {
$stmt->bindValue($key, $value);
}
$stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
// Exécuter la requête
$stmt->execute();
$livres = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Construire la réponse
$response = [
'data' => $livres,
'pagination' => [
'page' => $page,
'limit' => $limit,
'total' => (int)$total,
'pages' => ceil($total / $limit)
]
];
// Retourner la réponse JSON
header('Content-Type: application/json');
echo json_encode($response, JSON_PRETTY_PRINT);
?>
2. Endpoint POST - Créer un livre
<?php
// Connexion à la base de données (même code que précédemment)
// ...
// Récupérer les données JSON envoyées
$input = file_get_contents('php://input');
$data = json_decode($input, true);
// Validation des données
$errors = [];
if (empty($data['titre'])) {
$errors[] = ['field' => 'titre', 'message' => 'Le titre est obligatoire'];
}
if (empty($data['auteur'])) {
$errors[] = ['field' => 'auteur', 'message' => "L'auteur est obligatoire"];
}
if (!isset($data['annee']) || $data['annee'] < 1000 || $data['annee'] > date('Y')) {
$errors[] = ['field' => 'annee', 'message' => "L'année doit être valide"];
}
// Si erreurs, retourner 400
if (!empty($errors)) {
http_response_code(400);
echo json_encode([
'error' => [
'code' => 400,
'message' => 'Données invalides',
'validation_errors' => $errors
]
]);
exit;
}
// Préparer la requête INSERT
$sql = "INSERT INTO livre (titre, auteur, annee, isbn, prix, disponible)
VALUES (:titre, :auteur, :annee, :isbn, :prix, :disponible)";
$stmt = $pdo->prepare($sql);
try {
$stmt->execute([
':titre' => $data['titre'],
':auteur' => $data['auteur'],
':annee' => $data['annee'],
':isbn' => $data['isbn'] ?? null,
':prix' => $data['prix'] ?? 0,
':disponible' => $data['disponible'] ?? true
]);
// Récupérer l'ID du livre créé
$livreId = $pdo->lastInsertId();
// Récupérer le livre complet
$stmt = $pdo->prepare("SELECT * FROM livre WHERE id = :id");
$stmt->execute([':id' => $livreId]);
$livre = $stmt->fetch(PDO::FETCH_ASSOC);
// Retourner 201 Created
http_response_code(201);
echo json_encode([
'success' => true,
'message' => 'Livre créé avec succès',
'data' => $livre
], JSON_PRETTY_PRINT);
} catch (PDOException $e) {
http_response_code(500);
echo json_encode([
'error' => [
'code' => 500,
'message' => 'Erreur lors de la création du livre'
]
]);
}
?>
3. Endpoint PUT - Modifier un livre
<?php
// Récupérer l'ID depuis l'URL
$id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
if ($id === 0) {
http_response_code(400);
echo json_encode(['error' => 'ID invalide']);
exit;
}
// Vérifier que le livre existe
$stmt = $pdo->prepare("SELECT * FROM livre WHERE id = :id");
$stmt->execute([':id' => $id]);
$livre = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$livre) {
http_response_code(404);
echo json_encode(['error' => 'Livre non trouvé']);
exit;
}
// Récupérer les nouvelles données
$input = file_get_contents('php://input');
$data = json_decode($input, true);
// Préparer la requête UPDATE
$sql = "UPDATE livre SET
titre = :titre,
auteur = :auteur,
annee = :annee,
isbn = :isbn,
prix = :prix,
disponible = :disponible
WHERE id = :id";
$stmt = $pdo->prepare($sql);
try {
$stmt->execute([
':titre' => $data['titre'],
':auteur' => $data['auteur'],
':annee' => $data['annee'],
':isbn' => $data['isbn'] ?? null,
':prix' => $data['prix'] ?? 0,
':disponible' => $data['disponible'] ?? true,
':id' => $id
]);
// Récupérer le livre mis à jour
$stmt = $pdo->prepare("SELECT * FROM livre WHERE id = :id");
$stmt->execute([':id' => $id]);
$livre = $stmt->fetch(PDO::FETCH_ASSOC);
http_response_code(200);
echo json_encode([
'success' => true,
'message' => 'Livre modifié avec succès',
'data' => $livre
], JSON_PRETTY_PRINT);
} catch (PDOException $e) {
http_response_code(500);
echo json_encode(['error' => 'Erreur lors de la modification']);
}
?>
4. Endpoint DELETE - Supprimer un livre
<?php
$id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
if ($id === 0) {
http_response_code(400);
echo json_encode(['error' => 'ID invalide']);
exit;
}
// Vérifier que le livre existe
$stmt = $pdo->prepare("SELECT * FROM livre WHERE id = :id");
$stmt->execute([':id' => $id]);
if (!$stmt->fetch()) {
http_response_code(404);
echo json_encode(['error' => 'Livre non trouvé']);
exit;
}
// Supprimer le livre
$stmt = $pdo->prepare("DELETE FROM livre WHERE id = :id");
try {
$stmt->execute([':id' => $id]);
http_response_code(200);
echo json_encode([
'success' => true,
'message' => 'Livre supprimé avec succès'
]);
} catch (PDOException $e) {
http_response_code(500);
echo json_encode(['error' => 'Erreur lors de la suppression']);
}
?>
5. Tester l'API avec JavaScript (Fetch)
// 1. Récupérer tous les livres
async function getAllLivres() {
try {
const response = await fetch('/api/livre?page=1&limit=10');
const data = await response.json();
console.log('Livres:', data);
} catch (error) {
console.error('Erreur:', error);
}
}
// 2. Récupérer un livre spécifique
async function getLivre(id) {
try {
const response = await fetch(`/api/livre/${id}`);
if (!response.ok) {
throw new Error('Livre non trouvé');
}
const data = await response.json();
console.log('Livre:', data);
} catch (error) {
console.error('Erreur:', error);
}
}
// 3. Créer un nouveau livre
async function createLivre(livreData) {
try {
const response = await fetch('/api/livre', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(livreData)
});
const data = await response.json();
if (response.ok) {
console.log('Livre créé:', data);
} else {
console.error('Erreur:', data.error);
}
} catch (error) {
console.error('Erreur:', error);
}
}
// 4. Modifier un livre
async function updateLivre(id, livreData) {
try {
const response = await fetch(`/api/livre/${id}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(livreData)
});
const data = await response.json();
console.log('Livre modifié:', data);
} catch (error) {
console.error('Erreur:', error);
}
}
// 5. Supprimer un livre
async function deleteLivre(id) {
try {
const response = await fetch(`/api/livre/${id}`, {
method: 'DELETE'
});
const data = await response.json();
console.log('Résultat:', data);
} catch (error) {
console.error('Erreur:', error);
}
}
// Exemples d'utilisation
getAllLivres();
getLivre(5);
createLivre({
titre: 'Nouveau livre',
auteur: 'Auteur Test',
annee: 2026,
prix: 19.99
});
updateLivre(5, { titre: 'Titre modifié' });
deleteLivre(10);
Exercices pratiques
Créer une API simple de produits
Objectif : Créer une API REST pour gérer des produits (nom, prix, description)
Étapes :
- Créer une table
produitavec les champs : id, nom, prix, description - Créer un endpoint
GET /api/produitpour lister tous les produits - Créer un endpoint
GET /api/produit/{id}pour un produit spécifique - Tester avec un navigateur ou Postman
Ajouter la pagination et le filtrage
Objectif : Améliorer l'API de l'exercice 1 avec pagination et recherche
Critères :
- Ajouter les paramètres
?page=et?limit= - Ajouter un paramètre
?search=pour filtrer par nom - Retourner les infos de pagination dans la réponse JSON
- Gérer les cas d'erreur (page invalide, etc.)
Implémenter POST, PUT et DELETE
Objectif : Compléter le CRUD complet pour l'API produits
À faire :
- POST /api/produit : créer un nouveau produit
- PUT /api/produit/{id} : modifier un produit
- DELETE /api/produit/{id} : supprimer un produit
- Valider les données entrantes
- Retourner les bons codes HTTP (201, 200, 204, 400, 404)
Créer une API avec relations
Objectif : Gérer deux tables liées (categorie et produit)
Structure :
- Table
categorie: id, nom - Table
produit: id, nom, prix, categorie_id
Endpoints à créer :
- GET /api/categorie : liste des catégories
- GET /api/categorie/{id}/produit : produits d'une catégorie
- GET /api/produit/{id} : produit avec info de catégorie (JOIN)
API de gestion d'événements
Objectif : Créer une API complète pour gérer des événements
Fonctionnalités :
- CRUD complet sur les événements (titre, date, lieu, description)
- Filtrer par date (événements futurs/passés)
- Recherche par mot-clé
- Pagination
- Validation complète des données
- Gestion d'erreurs robuste
- Documentation de l'API (liste des endpoints)
Glossaire
API (Application Programming Interface)
Interface qui permet à des applications de communiquer entre elles. Ensemble de règles et de protocoles.
REST (Representational State Transfer)
Style d'architecture pour créer des services web basés sur HTTP.
Endpoint
URL spécifique qui expose une fonctionnalité de l'API (ex: /api/livre).
JSON (JavaScript Object Notation)
Format de données léger et lisible utilisé pour échanger des informations.
CRUD
Create, Read, Update, Delete - Les 4 opérations de base sur les données.
Query String
Partie de l'URL après le ? contenant des paramètres (ex: ?page=1&limit=10).
Path Parameter
Paramètre intégré dans le chemin de l'URL (ex: /api/livre/{id}).
Stateless (Sans état)
Principe où le serveur ne conserve pas d'informations sur les requêtes précédentes du client.
Router
Composant qui analyse l'URL et dirige la requête vers le bon contrôleur.
HTTP Status Code
Code numérique indiquant le résultat d'une requête (200 = succès, 404 = non trouvé, etc.).
Header HTTP
Métadonnées envoyées avec une requête ou réponse HTTP (Content-Type, Authorization, etc.).
Payload
Données envoyées dans le corps (body) d'une requête HTTP (POST, PUT, PATCH).
Éditeur Markdown
Testez du markdown en temps réel :