Nouveau : Datasets open source gratuits disponibles !Decouvrir →
🐘
Intermediaire 30 min Symfony

API REST avec Symfony

Pourquoi API REST avec Symfony ?

Les API REST (Representational State Transfer) sont un modèle d'architecture logicielle qui permet de créer des services web interopérables et évolutifs. En tant que développeur Symfony, vous aurez souvent besoin de créer des APIs pour communiquer entre différents systèmes ou pour exposer certaines fonctionnalités de votre application à d'autres applications.

Un cas concret de l'utilisation d'une API REST avec Symfony est lorsqu'un site web nécessite d'intégrer une application mobile. Le backend de l'application web expose une API REST qui peut être consommée par l'application mobile pour récupérer les données nécessaires.

Prerequis

Concepts fondamentaux

1. Contrôleur (Controller)

Un contrôleur est une classe qui gère les requêtes HTTP et retourne la réponse appropriée. Chaque action du contrôleur correspond à une route spécifique.

Code :

// src/Controller/TaskController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;

class TaskController extends AbstractController
{
    public function index(): Response
    {
        return $this->render('task/index.html.twig');
    }
}

2. Route (Routing)

Les routes définissent les URL que votre application va gérer et où ces URLs pointent. Symfony utilise le YAML pour définir les routes.

Code :

## config/routes.yaml
app_tasks_index:
    path: /tasks
    controller: App\Controller\TaskController::index

3. Entité (Entity)

Les entités représentent les données de votre application. Symfony utilise Doctrine comme ORM pour gérer les entités.

Code :

// src/Entity/Task.php
namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\TaskRepository")
 */
class Task
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $name;

    // Getters and setters
}

4. Repository (Repository)

Les repositories sont responsables de récupérer les données des entités à partir de la base de données.

Code :

// src/Repository/TaskRepository.php
namespace App\Repository;

use App\Entity\Task;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Symfony\Bridge\Doctrine\RegistryInterface;

class TaskRepository extends ServiceEntityRepository
{
    public function __construct(RegistryInterface $registry)
    {
        parent::__construct($registry, Task::class);
    }

    // Custom query methods
}

5. Serializer (Serializer)

Le serializer permet de convertir les entités en données JSON ou XML pour une réponse API.

Code :

## config/packages/serialization.yaml
framework:
    serialization:
        enable_annotations: true

Mise en pratique : projet fil rouge

Étape 1 : Créer le projet Symfony

Commencez par créer un nouveau projet Symfony :

composer create-project symfony/website-skeleton api-rest-symfony
cd api-rest-symfony

Étape 2 : Installer les dépendances

Installez les dépendances nécessaires pour l'API REST :

composer require doctrine/doctrine-bundle doctrine/orm annotations
composer require symfony/maker-bundle --dev
composer require nelmio/api-doc-bundle --dev

Étape 3 : Créer une entité Task

Créez une nouvelle entité Task :

// src/Entity/Task.php
namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\TaskRepository")
 */
class Task
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $name;

    // Getters and setters
}

Étape 4 : Créer un repository pour la table Task

Créez un repository pour la table Task :

// src/Repository/TaskRepository.php
namespace App\Repository;

use App\Entity\Task;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Symfony\Bridge\Doctrine\RegistryInterface;

class TaskRepository extends ServiceEntityRepository
{
    public function __construct(RegistryInterface $registry)
    {
        parent::__construct($registry, Task::class);
    }

    // Custom query methods
}

Étape 5 : Créer un service pour les tâches

Créez un service pour gérer les opérations CRUD sur les tâches :

// src/Service/TaskService.php
namespace App\Service;

use App\Entity\Task;
use App\Repository\TaskRepository;
use Doctrine\ORM\EntityManagerInterface;

class TaskService
{
    private $entityManager;
    private $repository;

    public function __construct(EntityManagerInterface $entityManager, TaskRepository $repository)
    {
        $this->entityManager = $entityManager;
        $this->repository = $repository;
    }

    public function findAll(): array
    {
        return $this->repository->findAll();
    }

    public function create(string $name): Task
    {
        $task = new Task();
        $task->setName($name);

        $this->entityManager->persist($task);
        $this->entityManager->flush();

        return $task;
    }

    // Other methods (update, delete)
}

Étape 6 : Créer un contrôleur pour les tâches

Créez un contrôleur pour gérer les routes API REST :

// src/Controller/TaskController.php
namespace App\Controller;

use App\Entity\Task;
use App\Service\TaskService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;

class TaskController extends AbstractController
{
    private $taskService;

    public function __construct(TaskService $taskService)
    {
        $this->taskService = $taskService;
    }

    /**
     * @Route("/tasks", name="app_tasks_index", methods={"GET"})
     */
    public function index(): JsonResponse
    {
        $tasks = $this->taskService->findAll();
        return $this->json($tasks);
    }

    /**
     * @Route("/tasks", name="app_tasks_create", methods={"POST"})
     */
    public function create(Request $request): JsonResponse
    {
        $name = $request->get('name');
        $task = $this->taskService->create($name);

        return $this->json($task, 201);
    }
}

Étape 7 : Configurer les routes

Ajoutez les routes pour le contrôleur TaskController dans config/routes.yaml :

app_tasks_index:
    path: /tasks
    controller: App\Controller\TaskController::index
    methods: [GET]

app_tasks_create:
    path: /tasks
    controller: App\Controller\TaskController::create
    methods: [POST]

Étape 8 : Tester l'API

Vous pouvez tester l'API en utilisant Postman ou curl. Voici un exemple avec curl :

## GET all tasks
curl -X GET http://localhost:8000/tasks

## POST a new task
curl -X POST -H "Content-Type: application/json" -d '{"name":"New Task"}' http://localhost:8000/tasks

Erreurs frequentes et debugging

1. Mauvais : Erreur de syntaxe dans le contrôleur

// ❌ Mauvais
public function create(Request $request): JsonResponse
{
    $name = $request->get('name');
    $task = new Task();
    $task->setName($name);

    return $this->json($task, 201);
}
symfony
## ✅ Correct
public function create(Request $request): JsonResponse
{
    $name = $request->get('name');
    $task = new Task();
    $task->setName($name);

    return $this->json($task, 201);
}

2. Mauvais : Erreur de connexion à la base de données

## ❌ Mauvais
php bin/console doctrine:schema:update --force
symfony
## ✅ Correct
php bin/console doctrine:schema:update --force

3. Mauvais : Erreur d'autorisation

// ❌ Mauvais
public function create(Request $request): JsonResponse
{
    $name = $request->get('name');
    $task = new Task();
    $task->setName($name);

    return $this->json($task, 201);
}
symfony
## ✅ Correct
use Symfony\Component\Security\Core\User\UserInterface;

public function create(Request $request, UserInterface $user): JsonResponse
{
    $name = $request->get('name');
    $task = new Task();
    $task->setName($name);

    return $this->json($task, 201);
}

Pour aller plus loin

1. Authentification et autorisation avec JWT

Intégrez l'authentification JWT pour sécuriser votre API.

2. Validation des données

Utilisez Symfony Validator pour valider les données entrantes.

3. Documentation de l'API avec Swagger/OpenAPI

Générer la documentation automatique de votre API avec Swagger/OpenAPI.

Défi pratique

Créez une application simple d'un gestionnaire de tâches où les utilisateurs peuvent créer, lire, mettre à jour et supprimer des tâches. Assurez-vous que l'application est sécurisée avec JWT et qu'elle dispose d'une documentation Swagger générée automatiquement.

Besoin d'aide sur Symfony ?

Besoin d'aide sur un projet technique ? Decrivez-le pour des conseils personnalises.

Recevoir des conseils

Pages liees

Chaque semaine, le meilleur de la tech francaise

Tendances, salaires, outils et opportunites — directement dans votre boite mail.

Gratuit. Desabonnement en un clic. Pas de spam.