Objectif
Créer une API REST CRUD complète pour des articles avec Laravel, SQLite, validation et réponses JSON structurées.
Stack : Laravel 11 · SQLite · Route::apiResource · StoreArticleRequest · UpdateArticleRequest
Endpoints
| Méthode | URL | Description | Réponse |
|---|---|---|---|
| GET | /api/articles | Lister (paginé) | 200 + { data, links, meta } |
| POST | /api/articles | Créer | 201 + { data } |
| GET | /api/articles/{id} | Détail | 200 + { data } |
| PUT | /api/articles/{id} | Modifier | 200 + { data } |
| DELETE | /api/articles/{id} | Supprimer | 204 |
Structure
02-laravel-fondamentaux/mini-projet/solution/
├── app/
│ ├── Http/
│ │ ├── Controllers/ArticleController.php
│ │ └── Requests/
│ │ ├── StoreArticleRequest.php
│ │ └── UpdateArticleRequest.php
│ └── Models/Article.php
├── database/
│ └── migrations/xxxx_create_articles_table.php
├── routes/api.php
└── README.md
Setup
cd 02-laravel-fondamentaux/mini-projet/solution
# Copier un projet Laravel existant ou créer
composer create-project laravel/laravel .
# Configurer SQLite
echo "DB_CONNECTION=sqlite" >> .env
touch database/database.sqlite
# Lancer les migrations
php artisan migrate
# Démarrer le serveur
php artisan serve
# → http://localhost:8000
Tests curl
# Lister tous les articles
curl http://localhost:8000/api/articles
# Créer un article
curl -X POST http://localhost:8000/api/articles \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"title":"Mon premier article","body":"Contenu...","status":"draft"}'
# Voir un article
curl http://localhost:8000/api/articles/1
# Modifier
curl -X PUT http://localhost:8000/api/articles/1 \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"title":"Titre modifié","status":"published"}'
# Supprimer
curl -X DELETE http://localhost:8000/api/articles/1
# Pagination
curl "http://localhost:8000/api/articles?page=2"
# Validation : titre manquant → 422
curl -X POST http://localhost:8000/api/articles \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"body":"Sans titre"}'
# → {"message":"Le titre est obligatoire.","errors":{"title":["Le titre est obligatoire."]}}