Objectif : Créer des interfaces de programmation (API) pour permettre à des clients (web, mobile, IoT) d’interagir avec votre application Symfony de manière sécurisée et standardisée.
Symfony :
Quelques définitions (et rappels) :
Création d’une API RESTful avec Symfony
composer require api # Installe API Platform, Symfony Serializer, etc.
composer require lexik/jwt-authentication-bundle # Pour l'authentification JWTapi_platform:
title: 'Mon API Symfony'
description: 'Une API pour mon application.'
version: '1.0.0'
formats:
jsonld:
mime_types: ['application/ld+json']
json:
mime_types: ['application/json']api:
resource: .
type: api_platform
prefix: /apiExemple de création d’une ressource API : Entité Book
// src/Entity/Book.php
namespace App\Entity;
use ApiPlatform\Metadata\ApiResource;
use Doctrine\ORM\Mapping as ORM;
#[ApiResource] // Annotation pour exposer l'entité comme ressource API
#[ORM\Entity]
class Book
{
#[ORM\Id, ORM\GeneratedValue, ORM\Column]
private ?int $id = null;
#[ORM\Column]
public string $title;
#[ORM\Column]
public string $author;
#[ORM\Column]
public int $year;
// Getters et setters...
}
Ajouter des filtres
use ApiPlatform\Metadata\ApiFilter;
use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
#[ApiResource]
#[ApiFilter(SearchFilter::class, properties: ['title' => 'partial'])]
class Book { ... }
GET /api/books?title=Symfony
→ Filtre les livres dont le titre contient "Symfony". #[ApiResource(
operations: [
new GetCollection(),
new Post(),
new Get(),
// new Put(), // Désactivé
// new Delete(), // Désactivé
]
)]
class Book { ... }Sérialisation et désérialisation
Exemple : Personnaliser la sérialisation pour exclure le champ author (il n'est pas inclus dans les requêtes POST)
// src/Entity/Book.php
use Symfony\Component\Serializer\Annotation\Groups;
#[ApiResource(
normalizationContext: ['groups' => ['book:read']],
denormalizationContext: ['groups' => ['book:write']]
)]
class Book
{
#[Groups(['book:read'])]
private ?int $id = null;
#[Groups(['book:read', 'book:write'])]
public string $title;
#[Groups(['book:read'])]
public string $author;
}
// src/Entity/Book.php
#[ORM\ManyToOne(targetEntity: Author::class)]
#[Groups(['book:read', 'book:write'])]
public Author $author;Authentification et sécurité
# config/packages/security.yaml
security:
providers:
jwt:
lexik_jwt: ~
firewalls:
api:
pattern: ^/api
stateless: true
jwt: ~` mkdir -p config/jwt
openssl genpkey -out config/jwt/private.pem -aes256 -algorithm rsa -pkeyopt rsa_keygen_bits:4096
openssl pkey -in config/jwt/private.pem -out config/jwt/public.pem -pubout curl -X POST -H "Content-Type: application/json" http://localhost:8000/api/login_check -d '{"username":"toto@webmail.ia","totopassword":"totopassword"}'{ "token": "token_jwt_reçu" } curl -H "Authorization: Bearer token_jwt_reçu" http://localhost:8000/api/books #[ApiResource(
security: "is_granted('ROLE_USER')"
)]
class Book { ... }Documentation de l’API
php bin/console api:openapi:export --output=openapi.json # config/api_platform/openapi.yaml
openapi: 3.0.0
info:
title: Mon API Symfony
version: 1.0.0
paths:
/api/books:
get:
summary: Liste des livres
responses:
200:
description: OKExemple Complet ;
Entité book
// src/Entity/Book.php
namespace App\Entity;
use ApiPlatform\Metadata\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Serializer\Annotation\Groups;
#[ApiResource(
normalizationContext: ['groups' => ['book:read']],
denormalizationContext: ['groups' => ['book:write']],
security: "is_granted('ROLE_USER')"
)]
#[ORM\Entity]
class Book
{
#[ORM\Id, ORM\GeneratedValue, ORM\Column]
#[Groups(['book:read'])]
private ?int $id = null;
#[ORM\Column]
#[Groups(['book:read', 'book:write'])]
#[Assert\NotBlank]
public string $title;
#[ORM\Column]
#[Groups(['book:read', 'book:write'])]
#[Assert\NotBlank]
public string $author;
#[ORM\Column]
#[Groups(['book:read', 'book:write'])]
#[Assert\Positive]
public int $year;
// Getters et setters...
}
| Méthode | Endpoint | Description | Exemple de requête |
|---|---|---|---|
| GET | /api/books | Liste des livres | curl -H "Authorization: Bearer TOKEN" http://localhost:8000/api/books |
| POST | /api/books | Créer un livre | curl -X POST -H "Authorization: Bearer TOKEN" -d '{"title":"Le cerveau solitaire","author":"Jeff Sutton","year":1974}' http://localhost:8000/api/books |
| GET | /api/books/{id} | Détails d’un livre | curl -H "Authorization: Bearer TOKEN" http://localhost:8000/api/books/1 |
| PUT | /api/books/{id} | Mettre à jour un livre | curl -X PUT -H "Authorization: Bearer TOKEN" -d '{"title":"Le nouveau cerveau solitaire"}' http://localhost:8000/api/books/1 |
| DELETE | /api/books/{id} | Supprimer un livre | curl -X DELETE -H "Authorization: Bearer TOKEN" http://localhost:8000/api/books/1 |
Ressources :