Symfony2 REST

Featured Image

Recently I started to write web services in my Symfony2 project that will provide JSON data for using with mobile and other devices that will consume that.

On the mobile side, RESTKIT will be used to connect to my services, and on my (web) side I used Symfony2 (of course).

So, let’s write a simple web service:

First of all, define route to choosen controller that will handle requests and responses from our web service:

_api_v1_get_user_locations:
    pattern:  /v1/locations/{_locale}.{_format}
    defaults: { _controller: SurgeworksApiBundle:Locations:getUserLocations, _format: json, _locale: en}
    requirements:
      _method:  GET
      _format: JSON

As you can see, I defined GET method in router. Locale is used for Symfony2 translator to localize response messages, but this is out of bounds of this article, and default_format is set to be JSON (for now). Format could be anything, later maybe I will implement XML response, but for now, this is enough.

Let’s make our controller:

//Surgeworks\ApiBundle\Controller\LocationsController.php
 
//...
 
    public function getUserLocationsAction() {
 
        //My symfony2 service for getting data from database and making
        //php array of it
        $result = $this->get('surgeworks_core.api')->getUserLocations();
 
        //Just convert array to JSON and return result
        return new Response(json_encode(array('locations' => $result)));
    }
 
//...
//Helloworld example
 
//Surgeworks\ApiBundle\Controller\HelloWorldController
 
public function getHelloWorldAction() {
 
$helloworld = array('hello' => 'world');
 
return new Response(json_encode(array('message' => $helloworld)));
}

That was example of GET method used. For POST, PUT and DELETE actions, principle is same, jut make sure to define required methods inside routing.yml file and make controller that will accept data provided, handle it and return wanted type of response (XML, JSON …)


7 comments

  1. Hi
    thank you for this tutorial,i have a problem please help me, i want to send from a mobile a json data to my rest webservice and i don’t know how to configure my web service to get the Json data from my mobile.

    thx you alot.

  2. Easy to use with many output formats:

    $serializer = new Serializer(array(), array(
    ‘json’ => new \Symfony\Component\Serializer\Encoder\JsonEncoder(),
    ‘xml’ => new \Symfony\Component\Serializer\Encoder\XmlEncoder()
    ));
    
    return new Response($serializer->encode($data, $this->getRequest()->get(‘_format’)));
  3. Easy to use with many output formats:

    $serializer = new Serializer(array(), array(
    ‘json’ => new \Symfony\Component\Serializer\Encoder\JsonEncoder(),
    ‘xml’ => new \Symfony\Component\Serializer\Encoder\XmlEncoder()
    ));

    return new Response($serializer->encode($data, $this->getRequest()->get(‘_format’)));

  4. Thanks for suggestion @Jonathan, Specific features in my project have needs to do it my way. Also, there is lot of customization with that, so it’s easier for me to implement manually features than refactoring and changing other bundles. 🙂

  5. I would suggest not hardcoding the version “v1” into the route name, but having a default that is the latest version. That way you can refer to the API route in, say, a template, and when “v2” arrives, you don’t have to replace all your v1_ routes with v2 – you just change the router config to have default version equal to v2. Also, check out the FOSRestBundle which looks like it could be similar to your results.

  6. Even without this, if defined in route, correct (json) content type will be returned anyway. Thanx for suggestion, Nemanja. 🙂

  7. I would also suggest returning the correct Content-type:

    return new Response(json_encode($response), 200, array(‘Content-type’ => ‘application/json’));

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <blockquote cite=""> <code> <del datetime=""> <em> <s> <strike> <strong>. You may use following syntax for source code: <pre><code>$current = "Inchoo";</code></pre>.