Rest Api with Symfony !
Introduction:
Developing a REST API is not an easy task because it’s hard to make changes once it’s released and It takes so much time designing the api.
Case study:
In my study project I have to develop a multi-platform application (a desktop, mobile, and web) So I preferred to use a REST approach to facilitate the work.
Those blog posts helped me to get through the setting up of the API.
Martin flower described the model very well .
Since I am going to use Symofny framework wiliam daurad’s blog post was very helpful.
Pre requires:
The objective here is to create a symfony Bundle inside my application that serves api for Offre (it’s written in French it means Offer) with get and post using symfony2 FOSRestBundle, the NelmioApiDocBundle, the JSMSerializerBundle, and Doctrine.
/*composer.json*/
"friendsofsymfony/rest-bundle": "1.*",
"jms/serializer-bundle": "0.13.*",
"nelmio/api-doc-bundle": "~2.8",appKerlnel.php
/*appKernel.php*/
new FOS\RestBundle\FOSRestBundle(),
new JMS\SerializerBundle\JMSSerializerBundle(),
new Nelmio\ApiDocBundle\NelmioApiDocBundle(),###Step 1 :The entity
This is my already implemented Offre entity
<?php
class Offre
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="etat", type="string", length=20, nullable=false)
*/
private $etat;
/**
* @var string
*
* @ORM\Column(name="typeImmob", type="string", length=20, nullable=false)
*/
private $typeimmob;
/** getters and setters*/
}?>actually we will not create a form for this entity we don’t recommand this but it is a choice for our project.
###Step 2: Offre Handler
<?php
class offreHandler
{
private $om;
private $offreClass;
private $repository;
// ..
public function __construct(ObjectManager $om, $offreClass)
{
$this->om = $om;
$this->offreClass = $offreClass;
$this->repository = $this->om->getRepository($this->offreClass);
}
?>this handler will serve the offres with get($id) to get a single offre and getAll($limit,$offset) for all offres with limit and offset parameters.
post(Request $parameters) to post offres.
<?php
public function getAll($limit = 5, $offset = 0)
{
return $this->repository->findBy(array(), null, $limit, $offset);
}
public function get($id)
{
return $this->repository->find($id);
}
public function post(Request $parameters)
{
$offre = new Offre(); // factory method create an empty Offre
return $this->processPost($offre, $parameters, 'POST');
}
?>processPost will do every thing, getting the attributes values and returning our offre object. like i said before we didn’t use the Form so we will get this attribute by attribute.
<?php
private function processPost(Offre $offre, Request $request, $method = "POST")
{
$etat=$request->get('etat');
$typeimmob=$request->get('typeimmob');
//we should also do the validation of our attributes
$offre->setEtat($etat);
$offre->setTypeimmob($typeimmob);
$this->om->persist($offre);
$this->om->flush($offre);
return $offre;
}
?>###Step 3 :The Controller
now after implementing our handler our work is to call those methodes in our offreController
<?
public function getOffresAction(Request $request, ParamFetcherInterface $paramFetcher)
{
$offset = $paramFetcher->get('offset');
$offset = null == $offset ? 0 : $offset;
$limit = $paramFetcher->get('limit');
$entities= $this->container
->get('rest.offre.handler')
->getAll($limit, $offset);
$view = $this->view($entities, 200)
->setTemplate("sprint2restBundle:Default:index.html.twig")
->setTemplateVar('entities') ;
return $this->handleView($view);
}
?>what is rest.offre.handler ??
rest.offre.handler is a service it will help us to access the handler and use its functionality wherever you need.
Service Container:
<parameters>
<parameter key="rest.offre.handler.class">sprint2\restBundle\Handler\offreHandler</parameter>
</parameters>
<services>
<service id="rest.offre.handler" class="%rest.offre.handler.class%">
<argument type="service" id="doctrine.orm.entity_manager" />
<argument>%rest.offre.class%</argument>
</service>
</services>for more documentation for the service container here the official symfony article
now let our api speak , we will use nemlio for that.
<?
/**
* Get All Offres,
*
* @ApiDoc(
* resource = true,
* description = "Gets All offres ",
*
* statusCodes = {
* 200 = "Returned when successful",
*
* }
* )
*
*@Annotations\View(templateVar="entities")
*@Annotations\QueryParam(name="offset", requirements="\d+", nullable=true, description="Offset from which to start listing offres.")
*@Annotations\QueryParam(name="limit", requirements="\d+", default="5", description="How many offres to return.")
*
*
*
* @param Request $request the request object
* @param ParamFetcherInterface $paramFetcher param fetcher service
*
*
* @return array
**/
public function getOffresAction(Request $request, ParamFetcherInterface $paramFetcher){...}
?>before going further we should see our work is going in the right direction , this is the routing.yml
sprint2rest_getOffres:
type: rest
prefix: /v1
resource: sprint2\restBundle\Controller\offreRestControllerthis should generate a route for us /v1/offres.{_format} to see this hit app/console router:debug | grep v1 you could access the api with curl -s or you can download chrome extension for rest api client or simply you can use the http command http localhost:8000/v1/offres.json
##The result:
debuging the router:

getting the result with http

Documentation:
