Symfony2 REST API
Posted on: 2014-11-15 | Categories:
PHP
In my recent project i had great opportunity to work together with powerful Symfony2 and amazing ExtJS5 frameworks. In the next few entries i will try to show you how to setup and configure Symfony2 application to serve REST API, than how to build ExtJS5 and AngularJS UI that will communicate with our REST API and finally how to setup basic authentication for REST API application… and maybe more.
Setup and configure Symfony2
Let’s start brand new Symfony 2.5 project (more information can be found on Installing and Configuring Symfony2 page):
|
$ composer create-project symfony/framework-standard-edition sfRest $ cd sfRest |
Don’t you have Composer installed yet?
Composer is the package manager used by modern PHP applications and the only recommended way to install Symfony2. To install Composer execute the following commands:
During the installation you will be asked for application database configuration – please provide proper parameters. For mailer configuration confirm default settings.
Notice: you will be also asked if you want to generate Acme demo bundle but we do not need it in our project.
JMSSerializerBundle
At the beginning we need to install JMSSerializerBundle
for entity serialization (to format such as JSON, XML, or YAML) and to be able to use some extra annotations like @ExclusionPolicy
, @Exclude
, @Expose
or @Type
. Full feature list and documentation can be found on bundle official website.
|
$ composer require jms/serializer-bundle |
and enable it in app/AppKernel.php
:
|
new JMS\SerializerBundle\JMSSerializerBundle() |
No extra configuration is necessary.
FOSRestBundle
FOSRestBundle
provides various tools to rapidly develop RESTful API’s & applications with Symfony2 framework. We will use this bundle to simplify the process of creating REST API.
Install FOSRestBundle
bundle:
|
$ composer require friendsofsymfony/rest-bundle ~1.4 |
Next step is to enable installed bundle – add the following line to AppKernel.php
:
|
new FOS\RestBundle\FOSRestBundle() |
set required configuration:
|
fos_rest: param_fetcher_listener: true body_listener: true format_listener: true view: view_response_listener: 'force' routing_loader: default_format: json |
and that’s it… for now.
Important: It is strongly advised to look over the 6 sections of documentation to have better understanding of core concepts
Resource
As REST is resource oriented (Resource-Oriented Architecture) – we need at least one resource for our example, e.g. User
resource.
Notice: The web itself is a RESTful service. In REST architecture almost everything is a resource, e.g. page/image/video/sound is a resource.
First we will create Level7 UserBundle
to store our REST API logic:
|
$ php app/console generate:bundle --namespace=Level7/UserBundle --dir=src --no-interaction |
Notice: DefaultController file can be deleted as we won’t need it.
… then we can generate empty User
entity to define our resource – empty because in the next step we are going to extend our resource class with FOSUserBundle/Model/User
.
|
$ php app/console doctrine:generate:entity --entity=Level7UserBundle:User --format=annotation --no-interaction |
FOSUserBundle
As in the near future we are going to implement some basic auth for API, this is a good place to install FOSUserBundle
for better user management and some other extra features.
According to FOSUserBundle documentation:
|
composer require friendsofsymfony/user-bundle "~2.0@dev" |
Enable it in AppKernel.php
:
|
new FOS\UserBundle\FOSUserBundle() |
Some required configuration app/config/config.yml
:
|
# FOSUserBundle fos_user: db_driver: orm firewall_name: main user_class: Level7\UserBundle\Entity\User |
and app/config/security.yml
:
|
security encoders: FOS\UserBundle\Model\UserInterface: sha512 |
Finally extend Level7UserBundle/Entity/Usert
with FOSUserBundle/Model/User
(aliased as BaseUser
):
Notice: --env=prod
parameter is not necessary but i just wanted to skip all DEV (development environment) routes.
UsersController: get users / user
First, we need to generate UsersController
controller using Symfony2
command line tool (or add it manually):
|
$ php app/console generate:controller --controller=Level7UserBundle:Users |
After that we need to add routing configuration to app/config/routing.yml
file:
|
level7_users: type: rest resource: Level7\UserBundle\Controller\UsersController |
We haven’t add any logic to UserController
so far. Lets add logic for two methods:
getUsersAction
will return all users
getUserAction
will return given user by id
Notice: Creating and deleting users will be introduced in next entry.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
// "get_users" [GET] /users public function getUsersAction() { $users = $this->getDoctrine() ->getRepository('Level7UserBundle:User') ->findAll(); return ['users' => $users]; } // "get_user" [GET] /users/{id} public function getUserAction($id) { $user = $this->getDoctrine() ->getRepository('Level7UserBundle:User') ->find($id); if (!$user) { throw $this->createNotFoundException(); } return ['user' => $user]; } |
This is really simple example but can be extended. What is more important, we don’t have to use any special code formatters or serializers to return proper JSON responses – thanks to FOSRestBundle
listeners that we configured in app/config/config.yml
file.
Testing Rest Api
The best way to verify that everything works as expected is to write some tests (recommended way) – in this example we are not going to write any tests. Instead, we will use great Google Chrome extension: Advanced Rest Client application to send some request and verify responses.
But before that let’s add some users to database – we can do that with fos:user:create
interactive command form shell:
|
$ php app/console fos:user:create |
After that we can make some test request with installed Advanced Rest Client
– if you have no virtual hosts configured, our REST API should be available on url http://localhost/sfRest/web/
+ resource routes according to implemented methods :
What’s next?
In the next entry we are going to implement postUsersAction
, putUserAction
, deleteUserAction
and also add some extra features like excluding / exposing entity properties or generating API doc.
The complete source code can be found on GitHub.
scourgen
February 3, 2015 08:33
you forgot to mention that you need add a router configuration in your router.yml. just like following:
Kamil
February 9, 2015 10:28
Hi,
I’ve added necessary information about generating
UsersController
controller and routing configuration, thanks for pointing out!Cheers
scourgen
February 3, 2015 08:38
the article is not bad,but in fact if you want it be useful, It’s better that you can check the whole process before you publish it. people who want read your article is someone that who doesn’t know how to do it, so you have to assume that they know nothing about everything .which means you have to write down everything you did on the project. at least make the projects works by following your article one step by one step. not make them got stuck and try to figure out that why something is not working
Kamil
February 9, 2015 10:11
Hi,
sorry for this
routing
section problem. I don’t assume that people who are reading blog entry aboutREST API
know nothing about Symfony2 and its components.You have also access to the source code on Github.
Cheers
Andy
February 25, 2015 10:33
Nice article, but where is the part with extjs 5? Haven’t found it 😉
Kamil
February 26, 2015 11:23
The post about ExtJS5 with Symfony2 REST API will be published soon – this is just the first part of the series.
vit
July 14, 2015 07:36
Nice article! But I’ve found 2 small typos(actually not presented in repo)
“After that we need to add routing configuration to app/config/config.yml file:”
routing.yml to be right
and pls reduce indent to
” resource: Level7\UserBundle\Controller\UsersController”
Kamil
July 14, 2015 10:37
Fixed, Thanks for letting me know!
Cheers.
mausly
November 15, 2015 19:48
Nice article but how to use an extern API REST like Google API, LinkedIn API, or owners ?
mausly
November 15, 2015 19:51
without guzzle (sorry)
Kamil
May 18, 2016 16:24
Hi,
I’m describing here how to set up simple REST API with Symfony2 and you are asking about Google / LinkedIn APIs… please read proper documentation. You don’t have to use Guzzle, you can user CURL for example 😉
Cheers,
Kamil