API REST - Documentation complète
Le DahoviTech Media Bundle expose une API REST complète basée sur API Platform, permettant la gestion programmatique de vos médias.
Base URL et Authentication
URL de base
https://your-domain.com/api/media
Authentication
L'API utilise l'authentication Symfony. Selon votre configuration :
# Token Bearer (recommandé)
Authorization: Bearer <your-token>
# Session-based
Cookie: PHPSESSID=<session-id>
Endpoints disponibles
Vue d'ensemble
| Méthode |
Endpoint |
Description |
| GET |
/api/media |
Liste tous les médias |
| GET |
/api/media/{id} |
Récupère un média spécifique |
| POST |
/api/media/upload |
Upload un fichier unique |
| POST |
/api/media/upload/multiple |
Upload multiple de fichiers |
| PUT |
/api/media/{id} |
Met à jour un média |
| DELETE |
/api/media/{id} |
Supprime un média |
| GET |
/api/media/search |
Recherche dans les médias |
| GET |
/api/media/{id}/download |
Télécharge un fichier |
| POST |
/api/media/{id}/duplicate |
Duplique un média |
| GET |
/api/media/statistics |
Statistiques (admin) |
| GET |
/api/media/types |
Types de médias supportés |
| GET |
/api/media/config |
Configuration API |
Détail des endpoints
1. Lister les médias
GET /api/media
Paramètres de requête
| Paramètre |
Type |
Description |
page |
integer |
Numéro de page (défaut: 1) |
limit |
integer |
Nombre d'éléments par page (défaut: 20, max: 100) |
type |
string |
Filtrer par type (image, document, pdf, other) |
search |
string |
Recherche dans nom, description, nom de fichier |
isPublic |
boolean |
Filtrer par statut public/privé |
mimeType |
string |
Filtrer par type MIME |
Exemple de requête
curl -X GET "https://your-domain.com/api/media?page=1&limit=10&type=image" \
-H "Accept: application/json"
Réponse
{
"data": [
{
"id": 1,
"name": "Mon image",
"description": "Description de l'image",
"filename": "abc123.jpg",
"originalFilename": "mon-image.jpg",
"mimeType": "image/jpeg",
"size": 256000,
"type": "image",
"width": 1920,
"height": 1080,
"isPublic": true,
"createdAt": "2024-01-15T10:30:00+00:00",
"updatedAt": "2024-01-15T10:30:00+00:00",
"url": "/uploads/media/abc123.jpg",
"thumbnailUrl": "/media/cache/thumbnail/abc123.jpg"
}
],
"pagination": {
"page": 1,
"limit": 10,
"total": 25,
"totalPages": 3
}
}
2. Récupérer un média
GET /api/media/{id}
Exemple de requête
curl -X GET "https://your-domain.com/api/media/1" \
-H "Accept: application/json"
Réponse
{
"id": 1,
"name": "Mon image",
"description": "Description détaillée",
"filename": "abc123.jpg",
"originalFilename": "mon-image.jpg",
"mimeType": "image/jpeg",
"size": 256000,
"type": "image",
"width": 1920,
"height": 1080,
"altText": "Texte alternatif",
"isPublic": true,
"hash": "def456",
"metadata": {
"camera": "Canon EOS R5",
"iso": 400,
"focal_length": "85mm"
},
"createdAt": "2024-01-15T10:30:00+00:00",
"updatedAt": "2024-01-15T10:30:00+00:00",
"expiresAt": null,
"url": "/uploads/media/abc123.jpg",
"thumbnailUrl": "/media/cache/thumbnail/abc123.jpg"
}
3. Upload d'un fichier unique
POST /api/media/upload
Headers requis
Content-Type: multipart/form-data
Paramètres
| Paramètre |
Type |
Requis |
Description |
file |
file |
Oui |
Le fichier à uploader |
name |
string |
Non |
Nom du média (généré auto si omis) |
description |
string |
Non |
Description du média |
isPublic |
boolean |
Non |
Statut public (défaut: true) |
Exemple de requête
curl -X POST "https://your-domain.com/api/media/upload" \
-H "Authorization: Bearer <token>" \
-F "file=@/path/to/image.jpg" \
-F "name=Mon image" \
-F "description=Description de mon image" \
-F "isPublic=true"
Exemple JavaScript
const formData = new FormData();
formData.append('file', fileInput.files[0]);
formData.append('name', 'Mon image');
formData.append('description', 'Description');
formData.append('isPublic', 'true');
fetch('/api/media/upload', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + token
},
body: formData
})
.then(response => response.json())
.then(media => console.log('Média créé:', media));
Réponse (201 Created)
{
"id": 2,
"name": "Mon image",
"description": "Description de mon image",
"filename": "xyz789.jpg",
"originalFilename": "image.jpg",
"mimeType": "image/jpeg",
"size": 512000,
"type": "image",
"width": 2048,
"height": 1536,
"isPublic": true,
"createdAt": "2024-01-15T11:00:00+00:00",
"updatedAt": "2024-01-15T11:00:00+00:00",
"url": "/uploads/media/xyz789.jpg",
"thumbnailUrl": "/media/cache/thumbnail/xyz789.jpg"
}
4. Upload multiple
POST /api/media/upload/multiple
Paramètres
| Paramètre |
Type |
Requis |
Description |
files[] |
file[] |
Oui |
Tableau de fichiers à uploader |
Exemple de requête
curl -X POST "https://your-domain.com/api/media/upload/multiple" \
-H "Authorization: Bearer <token>" \
-F "files[]=@/path/to/image1.jpg" \
-F "files[]=@/path/to/image2.jpg" \
-F "files[]=@/path/to/document.pdf"
Exemple JavaScript
const formData = new FormData();
for (let i = 0; i < fileInput.files.length; i++) {
formData.append('files[]', fileInput.files[i]);
}
fetch('/api/media/upload/multiple', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + token
},
body: formData
})
.then(response => response.json())
.then(result => console.log('Résultat:', result));
Réponse
{
"uploaded": {
"0": {
"id": 3,
"name": "Image1",
"filename": "abc123.jpg",
"type": "image"
},
"1": {
"id": 4,
"name": "Image2",
"filename": "def456.jpg",
"type": "image"
}
},
"errors": {
"2": "Type de fichier non autorisé"
},
"summary": {
"total": 3,
"success": 2,
"failed": 1
}
}
5. Mettre à jour un média
PUT /api/media/{id}
Headers
Content-Type: application/json
Paramètres
{
"name": "Nouveau nom",
"description": "Nouvelle description",
"altText": "Nouveau texte alternatif",
"isPublic": false,
"expiresAt": "2024-12-31T23:59:59+00:00"
}
Exemple de requête
curl -X PUT "https://your-domain.com/api/media/1" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <token>" \
-d '{
"name": "Nom mis à jour",
"description": "Description mise à jour",
"isPublic": false
}'
6. Supprimer un média
DELETE /api/media/{id}
Exemple de requête
curl -X DELETE "https://your-domain.com/api/media/1" \
-H "Authorization: Bearer <token>"
Réponse (200 OK)
{
"message": "Média supprimé avec succès"
}
7. Rechercher des médias
GET /api/media/search
Paramètres de requête
| Paramètre |
Type |
Requis |
Description |
q |
string |
Oui |
Terme de recherche (min 2 caractères) |
page |
integer |
Non |
Numéro de page |
limit |
integer |
Non |
Limite par page |
type |
string |
Non |
Filtrer par type |
isPublic |
boolean |
Non |
Filtrer par statut |
Exemple de requête
curl -X GET "https://your-domain.com/api/media/search?q=photo&type=image" \
-H "Accept: application/json"
Réponse
{
"query": "photo",
"data": [
{
"id": 1,
"name": "Photo de vacances",
"type": "image"
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 1,
"totalPages": 1
}
}
8. Télécharger un fichier
GET /api/media/{id}/download
Exemple de requête
curl -X GET "https://your-domain.com/api/media/1/download" \
-H "Authorization: Bearer <token>" \
-o "downloaded-file.jpg"
Headers de réponse
Content-Type: image/jpeg
Content-Disposition: attachment; filename="original-filename.jpg"
Content-Length: 256000
9. Dupliquer un média
POST /api/media/{id}/duplicate
Exemple de requête
curl -X POST "https://your-domain.com/api/media/1/duplicate" \
-H "Authorization: Bearer <token>"
Réponse (201 Created)
{
"id": 5,
"name": "Mon image (Copie)",
"filename": "ghi789.jpg",
"originalFilename": "original.jpg",
"type": "image"
}
10. Statistiques (Admin seulement)
GET /api/media/statistics
Exemple de requête
curl -X GET "https://your-domain.com/api/media/statistics" \
-H "Authorization: Bearer <admin-token>"
Réponse
{
"total": 150,
"by_type": [
{"type": "image", "count": 100},
{"type": "document", "count": 30},
{"type": "pdf", "count": 20}
],
"total_size": 52428800,
"average_size": 349525
}
11. Types supportés
GET /api/media/types
Réponse
{
"types": ["image", "document", "pdf", "other"],
"image_formats": ["jpg", "jpeg", "png", "gif", "webp"],
"document_formats": ["txt", "doc", "docx"],
"other_formats": ["pdf"]
}
12. Configuration API
GET /api/media/config
Réponse
{
"maxFileSize": 10485760,
"allowedExtensions": ["jpg", "jpeg", "png", "gif", "webp", "pdf", "txt", "doc", "docx"],
"allowedMimeTypes": [
"image/jpeg",
"image/png",
"image/gif",
"image/webp",
"application/pdf",
"text/plain"
]
}
Gestion des erreurs
Codes de statut HTTP
| Code |
Description |
| 200 |
Succès |
| 201 |
Créé avec succès |
| 400 |
Requête invalide |
| 401 |
Non authentifié |
| 403 |
Accès interdit |
| 404 |
Ressource non trouvée |
| 413 |
Fichier trop volumineux |
| 415 |
Type de média non supporté |
| 422 |
Entité non traitable |
| 500 |
Erreur serveur |
Format des erreurs
{
"error": "Message d'erreur descriptif",
"code": "ERROR_CODE",
"details": {
"field": "description de l'erreur"
}
}
Exemples d'erreurs courantes
Fichier trop volumineux
{
"error": "Le fichier est trop volumineux. Taille maximale autorisée : 10 Mo",
"code": "FILE_TOO_LARGE"
}
Type de fichier non autorisé
{
"error": "Type de fichier non autorisé : application/zip. Types autorisés : image/jpeg, image/png...",
"code": "INVALID_FILE_TYPE"
}
Validation échouée
{
"error": "Validation échouée",
"code": "VALIDATION_ERROR",
"details": {
"name": "Le nom est requis",
"file": "Le fichier est requis"
}
}
Exemples d'intégration
JavaScript (Fetch API)
class MediaAPI {
constructor(baseURL, token) {
this.baseURL = baseURL;
this.token = token;
}
async getMedias(filters = {}) {
const params = new URLSearchParams(filters);
const response = await fetch(`${this.baseURL}/api/media?${params}`, {
headers: {
'Authorization': `Bearer ${this.token}`,
'Accept': 'application/json'
}
});
return response.json();
}
async uploadFile(file, metadata = {}) {
const formData = new FormData();
formData.append('file', file);
Object.keys(metadata).forEach(key => {
formData.append(key, metadata[key]);
});
const response = await fetch(`${this.baseURL}/api/media/upload`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.token}`
},
body: formData
});
return response.json();
}
async deleteMedia(id) {
const response = await fetch(`${this.baseURL}/api/media/${id}`, {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${this.token}`
}
});
return response.json();
}
}
// Utilisation
const api = new MediaAPI('https://your-domain.com', 'your-token');
// Lister les médias
const medias = await api.getMedias({ type: 'image', page: 1 });
// Uploader un fichier
const fileInput = document.getElementById('file');
const media = await api.uploadFile(fileInput.files[0], {
name: 'Mon image',
description: 'Description'
});
PHP (avec Guzzle)
<?php
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Utils;
class MediaAPI
{
private Client $client;
private string $token;
public function __construct(string $baseURL, string $token)
{
$this->client = new Client(['base_uri' => $baseURL]);
$this->token = $token;
}
public function getMedias(array $filters = []): array
{
$response = $this->client->get('/api/media', [
'query' => $filters,
'headers' => [
'Authorization' => 'Bearer ' . $this->token,
'Accept' => 'application/json'
]
]);
return json_decode($response->getBody(), true);
}
public function uploadFile(string $filePath, array $metadata = []): array
{
$multipart = [
[
'name' => 'file',
'contents' => Utils::tryFopen($filePath, 'r'),
'filename' => basename($filePath)
]
];
foreach ($metadata as $key => $value) {
$multipart[] = [
'name' => $key,
'contents' => $value
];
}
$response = $this->client->post('/api/media/upload', [
'headers' => [
'Authorization' => 'Bearer ' . $this->token
],
'multipart' => $multipart
]);
return json_decode($response->getBody(), true);
}
}
// Utilisation
$api = new MediaAPI('https://your-domain.com', 'your-token');
// Lister les médias
$medias = $api->getMedias(['type' => 'image']);
// Uploader un fichier
$media = $api->uploadFile('/path/to/file.jpg', [
'name' => 'Mon image',
'description' => 'Description'
]);
CORS (Cross-Origin Resource Sharing)
Pour utiliser l'API depuis un navigateur avec un domaine différent, configurez CORS :
# config/packages/dahovi_tech_media.yaml
dahovi_tech_media:
api:
cors:
allowed_origins:
- 'https://monsite.com'
- 'https://admin.monsite.com'
allowed_methods: ['GET', 'POST', 'PUT', 'DELETE']
allowed_headers: ['Content-Type', 'Authorization']
Rate Limiting
Pour limiter les requêtes API, vous pouvez utiliser des bundles comme noxlogic/ratelimit-bundle :
# config/packages/noxlogic_rate_limit.yaml
noxlogic_rate_limit:
path_limits:
- { path: ^/api/media/upload, limit: 10, period: 60 }
- { path: ^/api/media, limit: 100, period: 60 }
Prochaines étapes