Files

128 lines
4.4 KiB
Markdown

# api-tube
API REST en PHP natif (POO) pour gérer des liens de vidéos YouTube.
- PHP natif uniquement : aucun framework, aucune dépendance, aucun Composer
- Stockage SQLite via PDO
## Prérequis
- PHP >= 8.1 avec l'extension `pdo_sqlite`
Activer l'extension si absente (Debian/Ubuntu) :
```bash
sudo apt install php8.5-sqlite3
php -m | grep -i sqlite # doit afficher pdo_sqlite et/ou sqlite3
```
## Lancement
```bash
php -S localhost:8000 -t public
```
La base `database/api_tube.sqlite` et son schéma sont créés automatiquement au premier appel (via les migrations).
## Migrations
Les migrations sont des fichiers SQL numérotés dans `database/migrations/`, appliqués une seule fois et tracés dans la table `migrations`.
Elles sont exécutées automatiquement à la connexion à la base. Pour les appliquer manuellement (hors serveur web) :
```bash
php database/migrate.php
```
Ajouter une migration :
```bash
# fichier database/migrations/002_ajout_colonne.sql
echo "ALTER TABLE links ADD COLUMN visible INTEGER DEFAULT 1;" > database/migrations/002_ajout_colonne.sql
php database/migrate.php
```
## Endpoints
| Méthode | Route | Description | Codes retour |
|---------|------------|----------------------------------------|--------------|
| GET | `/links` | Lister tous les liens | 200 |
| GET | `/links/{id}` | Lire un lien | 200 / 404 |
| POST | `/links` | Créer un lien | 201 / 409 / 422 |
| PUT | `/links/{id}` | Modifier un lien | 200 / 404 / 409 / 422 |
| DELETE | `/links/{id}` | Supprimer un lien | 204 / 404 |
### Corps attendu (POST / PUT, JSON)
```json
{
"title": "Titre de la vidéo",
"description": "Description",
"link_url": "https://youtube.com/watch?v=VIDEO_ID",
"thumbnail": "https://img.youtube.com/vi/VIDEO_ID/hqdefault.jpg"
}
```
`title` et `link_url` sont obligatoires ; `description` et `thumbnail` sont optionnels. `link_url` doit être une URL valide et unique.
## Tests manuels
```bash
bash tests/curl.sh
```
## Sécurité
Éléments de sécurité implémentés dans l'API :
- **Injection SQL** : toutes les requêtes avec paramètres utilisent des requêtes préparées PDO (`prepare()` + `execute()`) dans `src/LinkRepository.php`, jamais de concaténation de variables dans le SQL.
- **Validation des entrées** : champs obligatoires vérifiés, `trim()` systématique, et validation de `link_url` via `FILTER_VALIDATE_URL` (`src/LinkController.php`).
- **Pas de fuite d'informations** : toute erreur (base, rendu) renvoie une réponse 500 générique `Erreur interne du serveur.` sans stack trace ni détail (`public/index.php`). `display_errors` n'est pas activé.
- **Exposition minimale au web** : le DocumentRoot Apache (Docker) pointe vers `public/` uniquement ; `src/`, `database/` et la base SQLite ne sont pas servis publiquement. Le `.htaccess` réécrit toute requête vers `index.php`.
- **CORS restreint** : méthodes limitées à `GET, POST, PUT, DELETE, OPTIONS` et en-têtes à `Content-Type` (`public/index.php`).
- **Base hors de l'image Docker** : `*.sqlite` est exclu via `.dockerignore` et stocké dans le volume `db-data`, pas dans les layers de l'image.
- **Typage strict** : `declare(strict_types=1)` dans tous les fichiers PHP, paramètres et retours typés.
## Docker
### Lancement
```bash
docker compose up -d --build
# API accessible sur http://localhost:8000
```
### Arrêter
```bash
docker compose down # conserve la base (volume)
docker compose down -v # supprime la base (reset complet)
```
### Persistance
La base SQLite est stockée dans le Docker volume `db-data` : elle survit aux `down`/`up` successifs. Un `down -v` la supprime ; le prochain démarrage recrée la base via les migrations.
### Rebuild après modification du code
```bash
docker compose up -d --build
```
## Arborescence
```
public/
index.php # point d'entrée unique
.htaccess # réécriture vers index.php
src/
Database.php # connexion PDO SQLite + exécution des migrations
LinkRepository.php # CRUD SQL
LinkController.php # routage, validation, orchestration
database/
migrate.php # runner de migrations (CLI)
migrations/ # fichiers SQL versionnés
Dockerfile # image PHP 8.4 Apache + mod_rewrite
docker-compose.yml # service web + volume db-data
.dockerignore
```