Création d'une API REST sur Symfony

27 06 2017

21 commentaires

Création d'une API REST sur Symfony

Une API est conçue par des développeurs pour des développeurs. Le principe d'une API REST (Representational State Transfer) est de mettre à disposition des ressources à travers des url au format json ou xml. On met ainsi à disposition des url sur lesquelles un client Angular ou Symfony pourra venir effectuer des requêtes HTTP pour consommer cette API. Dans cette article nous allons voir comment créer une API REST avec Symfony.

Tout d'abord, il y a plusieurs niveaux pour définir une API REST. Les niveaux de conformité d'une API REST sont définis dans le modèle de maturité de Richardson.

  • niveau 0 : Le RPC sur HTTP en POX (Plain Old XML)
  • niveau 1 : L’utilisation de ressources différentiées
  • niveau 2 : L’utilisation des verbes HTTP
  • niveau 3 : L’utilisation des contrôles hypermédia

Une API qui répond aux 4 critères est dit pleinement REST ou Restful.

 

Utilité d'une API REST

L'utilité d'une API REST est de pouvoir lire des resources situées sur un serveur et de pouvoir les consommer depuis un autre serveur. L'échange de flux de données est ainsi qualifée de cross-domain. Pour cela nous aurons besoin de spécifier des entêtes spéciales pour autoriser un serveur à dialoguer avec un autre serveur. Car l'échange de flux de données cross-domain n'est pas autorisé par défaut. Pour cela nous aurons besoin de rajouter des entêtes spéciales de type CORS (Cross Origin Resource Sharing) avec notamment le control-access-allow-origin.

 

Configuration de Symfony

Pour créer une API REST avec Symfony, nous aurons besoin de 2 bundle:

  1. JMSSerializerBundle
  2. FOSRestBundle

JMSSerializerBundle va permettre de sérialiser les données au format json ou de les desérialiser en objet.

FOSRestBundle va permettre de simplifier la création de votre API REST grâce à une configuration spéciale de votre framework Symfony

Je n'expliquerai pas comment télécharger ces bundles, ni comment les activer. Pour cela consultez l'article Télécharger un bundle avec la commande require

Maintenant que ces 2 bundles ont été téléchargés et activés dans le appKernel.php, nous avons besoin de préciser dans le fichier config.yml la configuration de Symfony pour le bundle FOSRest:

fos_rest:
    param_fetcher_listener: true
    body_listener: true
    format_listener:
        rules:
            - { path: '^/api', priorities: ['json'], fallback_format: 'json' }
            - { path: '^/', priorities: ['html'], fallback_format: 'html' }
    view:
        view_response_listener: true
        formats:
            xml: true
            json : true
        templating_formats:
            html: true
        force_redirects:
            html: true
        failed_validation: HTTP_BAD_REQUEST
        default_engine: twig
    routing_loader:
        default_format: false
        include_format: false

 

Création d'une API REST

Nous allons maintenant créer notre controller placeController. Son rôle sera de pouvoir effectuer des actions sur des urls aux travers de verbes HTTP. Chaque action aura une méthode HTTP et une url qui lui sera propre. On pourra donc dire que notre API atteint le niveau 2 du modèle de maturité de Richardson.

Notre API va traité une entité Places qui contiendra 2 atrributs name et adress. Voici notre entité i:

<?php

namespace Blog\JournalBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * Places
 * @ORM\Table(name="places", uniqueConstraints={@ORM\UniqueConstraint(name="places_name_unique",columns={"name"})})
 * @ORM\Entity(repositoryClass="Blog\JournalBundle\Repository\PlacesRepository")
 */
class Places
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

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

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


    /**
     * Get id
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     *
     * @return Place
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set address
     *
     * @param string $address
     *
     * @return Place
     */
    public function setAddress($address)
    {
        $this->address = $address;

        return $this;
    }

    /**
     * Get address
     *
     * @return string
     */
    public function getAddress()
    {
        return $this->address;
    }
}

 

Et voici notre contrôleur placeController.php:

<?php
namespace Blog\JournalBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\View\View;
use Blog\JournalBundle\Entity\Places;
use Blog\JournalBundle\Form\PlacesType;

class PlaceController extends Controller
{

    /**
     * @Rest\View()
     * @Rest\Get("/places")
     */
    public function getPlacesAction(Request $request)
    {
        $places = $this->get('doctrine.orm.entity_manager')
                ->getRepository('JournalBundle:Places')
                ->findAll();
        
    return $places;
    }

   /**
     * @Rest\View()
     * @Rest\Get("/places/{id}")
     */
    public function getPlaceAction(Request $request)
    {
        $place = $this->get('doctrine.orm.entity_manager')
                ->getRepository('JournalBundle:Places')
                ->find($request->get('id'));
        /* @var $place Place */

        if (empty($place)) {
            return new JsonResponse(['message' => 'Place not found'], Response::HTTP_NOT_FOUND);
        }

        return $place;
    }

    /**
     * @Rest\View(statusCode=Response::HTTP_CREATED)
     * @Rest\Post("/places")
     */
    public function postPlaceAction(Request $request)
    {
        $place = new Places();
        $form = $this->createForm(PlacesType::class, $place);

        $form->submit($request->request->all());

        if ($form->isValid()) {
            $em = $this->get('doctrine.orm.entity_manager');
            $em->persist($place);
            $em->flush();
            return $place;
        } else {
            return $form;
        }
    }

     /**
     * @Rest\View(statusCode=Response::HTTP_NO_CONTENT)
     * @Rest\Delete("/places/{id}")
     */
    public function removePlaceAction(Request $request)
    {
        $em = $this->get('doctrine.orm.entity_manager');
        $place = $em->getRepository('JournalBundle:Places')
                    ->find($request->get('id'));
        /* @var $place Place */

        if ($place) {
            $em->remove($place);
            $em->flush();
        }
    }

    /**
     * @Rest\View()
     * @Rest\Put("/places/{id}")
     */
    public function updatePlaceAction(Request $request)
    {
        $em = $this->get('doctrine.orm.entity_manager');
        $place = $em->getRepository('JournalBundle:Places')
                    ->find($request->get('id'));

        if (empty($place)) {
            return new JsonResponse(['message' => 'Place not found'], Response::HTTP_NOT_FOUND);
        }

        $form = $this->createForm(PlacesType::class, $place);

        $form->submit($request->request->all());

        if ($form->isValid()) {
            $em = $this->get('doctrine.orm.entity_manager');
            $em->merge($place);
            $em->flush();
            return $place;
        } else {
            return $form;
        }
    }

    /**
     * @Rest\View()
     * @Rest\Patch("/places/{id}")
     */
    public function patchPlaceAction(Request $request)
    {
        $place = $this->get('doctrine.orm.entity_manager')
                ->getRepository('JournalBundle:Places')
                ->find($request->get('id'));

        if (empty($place)) {
            return new JsonResponse(['message' => 'Place not found'], Response::HTTP_NOT_FOUND);
        }

        $form = $this->createForm(PlacesType::class, $place);

        $form->submit($request->request->all(), false);

        if ($form->isValid()) {
            $em = $this->get('doctrine.orm.entity_manager');
            $em->merge($place);
            $em->flush();
            return $place;
        } else {
            return $form;
        }
    }
}

 

Notre API REST est à présent fonctionnelle. On va pouvoir tester notre API avec Postman. Puis nous pourrons consommer cette API avec un client comme Angular ou Symfony pour effectuer des requêtes dessus soit depuis le même serveur, soit depuis un autre serveur. Pour savoir comment faire vous pouvez lire notre article Consommer une API REST avec AngularJS.


 catégorie: Symfony


Commentaires

KelAncelo posté le 13/01/2019 à 14:56

Elimite <a href=http://genericvia.com>viagra prescription</a> Mail Order Macrobid Urinary Tract Infections Manyfacturing Amoxicillin <a href=http://buycial.com>cialis for sale</a> L Thyroxin Ohne Rezept Bestellen Viagra Farmacia Madrid Buy Tinidazole From India Online Cialis 10mg Nebenwirkungen <a href=http://gaprap.com>viagra</a> Amoxicillin And Teeth Amoxil Sur L' Forum Cialis Effets Secondaires


WilliamMic posté le 01/02/2019 à 17:14

cialis purchace on line fast no rx
is cialis by prescription only
<a href=https://kellyannehulme.com>cheap price</a>
pharmacy express belize cialis
cialis orosolubile
https://greatwinesgrandhouses.com
best price for cialis in usa
cialis 20 mg side effects
<a href=https://greatwinesgrandhouses.com>cheap price</a>
price of cialis without insurance
reputable cialis online
https://kellyannehulme.com


WilliamMic posté le 01/02/2019 à 18:55

buy cialis lilly
no prescription cialis online in canada
<a href=https://kellyannehulme.com>cialis</a>
generic cialis from us pharmacy
cialis from usa pharmacy
https://kellyannehulme.com
cialis 30 day free
cialis on line legal orders
<a href=https://kellyannehulme.com>Cheap cialis buy</a>
cialis generico vendita on line
cialis with out px
https://greatwinesgrandhouses.com


ArnoldRiz posté le 05/02/2019 à 09:39

generic cialis using mastercard
best price for cialis 5 mg 215
<a href="http://cialistlm.com">buy cialis</a>
bay cialis fast shipping
cialis e-shops europe
<a href="http://cialistlm.com">buy cialis</a>
best cheap cialis online
achat cialis generique
<a href="http://xcialisxx.com">Buy Cialis Online</a>


LesVomi posté le 19/02/2019 à 17:29

Prednisone Online Order Achat Cialis Andorre <a href=http://clanar.com>viagra</a> Viagra E Miopia Legally Levaquin Where To Buy Discount Overnight Shipping


Michaelcep posté le 25/02/2019 à 07:43

cialis italiacialis for sale sulitcialis tadalafil reviewsbph and cialis <a href="https://skylensnw.com/">cialis 40mg</a>
https://skylensnw.com
https://www.instapaper.com/read/1163280342
http://www.magcloud.com/user/ibrahimmcclure5
https://championsleage.review/wiki/Cialis10vs20


Michaelcep posté le 25/02/2019 à 13:41

cialis for sale fast delivericialis 5mg tablets australiacialis tablete cenabuy pfizer cialis <a href="https://skylensnw.com/">cialis 20 mg</a>
https://skylensnw.com
http://dou46magadan.ru/user/IbrahimIbrahim1/
http://menaheria.com/author/bjerregaardmcclure2/
https://rasmussenhinrichsen0452.page.tl/costo_cialis_originale_20_mg.htm?forceVersion=desktop


Michaelcep posté le 25/02/2019 à 21:14

cheap legitimate cialiscialis thailand prescription800 mg cialiscialis 20mg price comparison <a href="https://skylensnw.com/">cialis 60 mg</a>
https://skylensnw.com
https://www.addpoll.com/gilliamboesen6
http://siemensnx.com/index.php?qa=user&qa_1=filtenborgeliasen6
http://jpacschoolclubs.co.uk/index.php?option=com_k2&view=itemlist&task=user&id=2657798


Michaelcep posté le 26/02/2019 à 05:50

were to buy brand name cialisbuy cialis online in the uksuper cialis online20 mg cialis price <a href="https://skylensnw.com/">Buy cialis</a>
https://skylensnw.com
https://www.care2.com/c2c/people/profile.html?pid=476554632
https://acrelinux.stream/wiki/Cialiscouponsprintable2014
http://4share.pro/index.php?qa=user&qa_1=mcclureeliasen8


Michaelcep posté le 27/02/2019 à 07:51

cialis sales online usa paypalcialis daily use costbest cialis online reviewcialis toronto <a href="https://skylensnw.com/">Buy cialis 20mg</a>
https://skylensnw.com
http://hibookmark.tk/story.php?title=www-cialis-20m-tabalafil-4#discuss
http://jpacschoolclubs.co.uk/index.php?option=com_k2&view=itemlist&task=user&id=2657548
http://askpub.com/index.php?qa=user&qa_1=guptabjerregaard0


Michaelcep posté le 27/02/2019 à 13:55

buy cialis in portugalcialis internetapothekeis cialis from aurochem any goodcialis online quick delivery <a href="https://skylensnw.com/">cialis 20mg</a>
https://skylensnw.com
http://2.gp/MTQ6
https://lovewiki.faith/wiki/Enucuzcialis20mg
http://kinngseo.gq/story.php?title=original-cialis-20mg-price-1#discuss

http://ask.hindistudy.in/index.php?qa=user&qa_1=pena09douglas
https://www2.zippyshare.com/v/RtB5BoLA/file.html
https://tiny.cc/i1wf3y


Michaelcep posté le 28/02/2019 à 02:18

generic super cialiscialis generic from mexicobest cialis online pharmacycialis generika per nachnahme bestellen <a href="https://skylensnw.com/">Buy cialis 10 mg</a>
https://skylensnw.com
https://buzzon.khaleejtimes.com/author/gilliamjacobson0/
http://cort.as/-EvrO
http://philipsenraymond7.edublogs.org/2019/02/18/cialis-20-mg-x-30-pill-for-765/

https://sharenator.com/profile/lorentsen59douglas/
https://www.scribd.com/
http://backsitelinks.xyz/story.php?title=buy-cialis-from-%C2%A381p#discuss


Yrhaelcep posté le 09/03/2019 à 09:08

<a href="https://chatespaa.es/chat-gay-granada/">contactos gays granada</a>
<a href="https://chatespaa.es/chat-gay-sevilla-gay-chat-network/">contactos gay sevilla</a>
<a href="https://chatespaa.es/gay-chat-madrid/">trabestis en madrid</a>
<a href="https://chatespaa.es/">chat gay esp</a>


http://www.proskore.com/%e0%b8%96%e0%b8%ad%e0%b8%94%e0%b8%a3%e0%b8%ab%e0%b8%b1%e0%b8%aa%e0%b8%98%e0%b8%b8%e0%b8%a3%e0%b8%81%e0%b8%b4%e0%b8%88-%e0%b8%9e%e0%b8%ad%e0%b9%83%e0%b8%88-%e0%b8%9e%e0%b8%b8%e0%b8%81%e0%b8%81/?unapproved=15735&moderation-hash=78ab0c9851ba8928dc6c06b5acaf1c4c#comment-15735
http://dronegiant.com/forum/thread-199217.html
http://www.proskore.com/%e0%b8%98%e0%b8%b8%e0%b8%a3%e0%b8%81%e0%b8%b4%e0%b8%88-%e0%b8%82%e0%b8%b2%e0%b8%a2%e0%b8%82%e0%b8%ad%e0%b8%87%e0%b8%ad%e0%b8%ad%e0%b8%99%e0%b9%84%e0%b8%a5%e0%b8%99%e0%b9%8c/?unapproved=17974&moderation-hash=c6b6bd5d60cb6d575f27197b7e562100#comment-17974


LesVomi posté le 11/03/2019 à 20:49

Xenical Vente Libre Espagne <a href=http://leviplus.com>levitra samples</a> Propecia Generico En Madrid Viagra France Pharmacie Single Dosing Of Amoxicillin For Gonorrhea


WGgbWJ <a href="http://mwumarkxclrx.com/">mwumarkxclrx</a>, [url=http://rjdtsqfeogwu.com/]rjdtsqfeo posté le 27/03/2019 à 10:16

WGgbWJ <a href="http://mwumarkxclrx.com/">mwumarkxclrx</a>, [url=http://rjdtsqfeogwu.com/]rjdtsqfeogwu[/url], [link=http://kpbyfprcrhvi.com/]kpbyfprcrhvi[/link], http://pjpnzwhdlzin.com/


WTsBDY <a href="http://wvwkalhlxqxo.com/">wvwkalhlxqxo</a>, [url=http://fhkwkykqojwi.com/]fhkwkykqo posté le 29/03/2019 à 15:55

WTsBDY <a href="http://wvwkalhlxqxo.com/">wvwkalhlxqxo</a>, [url=http://fhkwkykqojwi.com/]fhkwkykqojwi[/url], [link=http://ecngtuqqzyyc.com/]ecngtuqqzyyc[/link], http://vszckvnsvtay.com/


Ellenrift posté le 08/04/2019 à 00:45

Kamagra Per Nachnahme Cialis Online Without Prescription Viagra For Men <a href=http://xzanax.com></a> Fish Amoxicillin Fluoxetine Buy By Money Order


oycbcwf posté le 30/04/2019 à 23:41

lO6xIe <a href="http://lhvexjoemzup.com/">lhvexjoemzup</a>, [url=http://pgxvnsofmgfk.com/]pgxvnsofmgfk[/url], [link=http://uxghtqkniyeo.com/]uxghtqkniyeo[/link], http://lbudmsyhtdxo.com/


BbokhygBow posté le 20/05/2019 à 01:33

The drink is also exported to African countries such as Uganda, Malawi and Zimbabwe, the manufacturer, Revin Ltd, said last year. <a href="https://viagraoktobuy.com/">generic viagra suppliers usa</a> html) bhang goli effect nullify Tags what is Zeagra Bhabhi par vigora tablet ka asar 2014.


generic viagra posté le 28/05/2019 à 17:50

A 1999 found that men between the ages of 50 and 59 were three-and-a-half times more likely to suffer from erectile dysfunction than men aged 18 to 29, and many more would experience other changes in their erections as they aged. <a href="https://viagraoktobuy.com/">buy viagra online</a> Specialty drugs require prior authorization from the doctor before we cover them.


best place to buy viagra online posté le 05/06/2019 à 13:03

Sağlık ekosisteminin kalbinde yer alan bir üniversite olarak sahip olduğu birikimin ve enerjinin yeni iş fikirleri için fırsata dönüşmesi hedefiyle Acıbadem Üniversitesi Kuluçka Merkezini Kerem Aydınlar Kampüsünde hayata geçiriyor. <a href="https://viagraoktobuy.com/">generic viagra online</a> At 170 min of reperfusion, vascular resistance within the RA was significantly lower in the sildenafil group ( P<0.05).



Laisser un commentaire