Construction d'API
1) Création d'un projet
composer create-project symfony/skeleton mon-API
2) Installer Apache, Annotation, JMS-serializer, Doctrine et Maker
cd mon-API
composer require symfony/apache-pack
composer require annotations
composer require jms/serializer-bundle
composer require symfony/orm-pack
composer require doctrine maker
3) Base de données
Dans .env
:
DATABASE_URL=mysql://root:''@127.0.0.1:3306/mon_api
php bin/console doctrine:database:create
4) Entité de test
php bin/console make:entity Article
Avec son 1er champ title, en string, 100 caractères, non-nullable ; et un 2ème champ content, en text, non-nullable.
php bin/console make:migration
php bin/console doctrine:migrations:migrate
5) Le contrôleur
Dans src / Controller créer un fichier de type MonApi.php :
php bin/console make:controller MonApi
Puis dans le fichier MonApiController.php :
<?php
namespace App\Controller;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use App\Entity\Article;
use Symfony\Component\HttpFoundation\Response;
class MonApiController extends Controller
{
/**
* @Route("/articles/{id}", name="article_show")
*/
public function showAction()
{
$article = new Article();
$article
->setTitle('Mon premier article')
->setContent('Le contenu de mon article.')
;
$data = $this->get('jms_serializer')->serialize($article, 'json');
$response = new Response($data);
$response->headers->set('Content-Type', 'application/json');
return $response;
}
}
L'URL http://localhost/mon-API/public/articles/1 doit renvoyer un json.
6) Postman
Installez l'extension Postman pour Chrome, et testez une requête GET sur l'URL http://localhost/mon-API/public/articles/1.
Postman doit bien renvoyer le même json, tel que décrit dans votre contrôleur, et visible dans un navigateur.
7) Requête Post
Modifions maintenant la classe de notre contrôleur afin d'être capable d'envoyer des données soumises par un cient :
...
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Component\HttpFoundation\Request;
...
/**
* @Route("/articles", name="article_create")
* @Method({"POST"})
*/
public function createAction(Request $request)
{
$data = $request->getContent();
$article = $this->get('jms_serializer')->deserialize($data, 'App\Entity\Article', 'json');
$em = $this->getDoctrine()->getManager();
$em->persist($article);
$em->flush();
return new Response('', Response::HTTP_CREATED);
}
...
Maintenant la route http://localhost/mon-API/public/articles attend des données en fonction de l'entité Article
, et sous forme de json.
L'URL elle-même ne fonctionne pas telle quelle, mais sous Postman, une requête de type Post avec des données json remplira bien la base de données.
8) Méthodes d'affichage
Modifions notre contrôleur afin d'afficher de vrais articles selon l'id ainsi que la liste complète des articles :
<?php
namespace App\Controller;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use App\Entity\Article;
use Symfony\Component\HttpFoundation\Response;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Component\HttpFoundation\Request;
class MonApiController extends Controller
{
/**
* @Route("/articles/{id}", name="article_show")
*/
public function showAction(Article $article)
{
$data = $this->get('jms_serializer')->serialize($article, 'json');
$response = new Response($data);
$response->headers->set('Content-Type', 'application/json');
return $response;
}
/**
* @Route("/articles", name="article_create")
* @Method({"POST"})
*/
public function createAction(Request $request)
{
$data = $request->getContent();
$article = $this->get('jms_serializer')->deserialize($data, 'App\Entity\Article', 'json');
$em = $this->getDoctrine()->getManager();
$em->persist($article);
$em->flush();
return new Response('', Response::HTTP_CREATED);
}
/**
* @Route("/articles_list", name="article_list")
* @Method({"GET"})
*/
public function listAction()
{
$articles = $this->getDoctrine()->getRepository('App:Article')->findAll();
$data = $this->get('jms_serializer')->serialize($articles, 'json');
$response = new Response($data);
$response->headers->set('Content-Type', 'application/json');
return $response;
}
}
9) Cacher des champs
Il faut modifier l'entité pour appeler le Serializer (use JMS\Serializer\Annotation as Serializer;
), cacher tous les champs (* @Serializer\ExclusionPolicy("ALL")
), puis en appeler certains (* @Serializer\Expose
) :
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as Serializer;
/**
* @ORM\Entity(repositoryClass="App\Repository\ArticleRepository")
* @Serializer\ExclusionPolicy("ALL")
*/
class Article
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=100)
* @Serializer\Expose
*/
private $title;
/**
* @ORM\Column(type="text")
* @Serializer\Expose
*/
private $content;
...
xx
xx
xx