Contents
I want to create a simple Resftul Web service for reading data in JSON format. On part I I´ll discuss the basics on how to configure the web service on part II I´ll discuss how to introduce pagination to the web service.
Requirements:
- PHP 5.3.6
- Netbeans 7.0.1
- Wamp 2.0
1 Installing Symfony2
- Download Symfony2 in zip format from http://symfony.com/download.
- Unzip the file. To your NetbeansProjects directory,
- Rename the symfony directory to mroute_rest_service.
- Open a command Window and move to the mroute_rest_service.directory.
Run:
php .\app\console --version
Symfony version 2.0.9 - app/dev/debug
2 Creating the Bundle
- On the command window run:
php .\app\console generate:bundle
Welcome to the Symfony2 bundle generator
Your application code must be written in bundles. This command helps
you generate them easily.
Each bundle is hosted under a namespace (like Acme/Bundle/BlogBundle).
The namespace should begin with a "vendor" name like your company name, your
project name, or your client name, followed by one or more optional category
sub-namespaces, and it should end with the bundle name itself
(which must have Bundle as a suffix).
Use / instead of \ for the namespace delimiter to avoid any problem.
- Fill as follows:
Bundle namespace: MyGIS/GISBundle
In your code, a bundle is often referenced by its name. It can be the
concatenation of all namespace parts but it's really up to you to come
up with a unique name (a good practice is to start with the vendor name).
Based on the namespace, we suggest MyGISGISBundle.
Bundle name [MyGISGISBundle]:
The bundle can be generated anywhere. The suggested default directory uses
the standard conventions.
Target directory [C:\NetbeansProjects\gis_rest_services/src]:
Determine the format to use for the generated configuration.
Configuration format (yml, xml, php, or annotation) [annotation]:
To help you getting started faster, the command can generate some
code snippets for you.
Do you want to generate the whole directory structure [no]?
Summary before generation
You are going to generate a "MyGIS\GISBundle\MyGISGISBundle" bundle
in "C:\NetbeansProjects\gis_rest_services/src/" using the "annotation" format.
Do you confirm generation [yes]?
Bundle generation
Generating the bundle code: OK
Checking that the bundle is autoloaded: OK
Confirm automatic update of your Kernel [yes]?
Enabling the bundle inside the Kernel: OK
Confirm automatic update of the Routing [yes]?
Importing the bundle routing resource: OK
You can now start using the generated code!
3 Generating Doctrine Entities
We are going to to have two entities Route and Points.
- On the command window run:
php .\app\console gen:doctrine:entity
- On Entity shortcut name type MyGISGISBundle:MRoute
- Accept defualt configuration format annotation
- Add the fields as follows:
- Name
Field name: name
Field type: string
Field length: 125
- Name
- On Do you want to generate an empty repository class answer yes
- On the command window run:
php .\app\console gen:doctrine:entity
- On Entity shortcut name type MyGISGISBundle:Point
- Accept defualt configuration format annotation
- Add the fields as follows:
- Name
Field name: name
Field type: string
Field length: 50
- X
Field name: x
Field type: decimal
- Y
Field name: y
Field type: decimal
- PType
Field name: pType
Field type: string
Field length: 25
- Name
- On Do you want to generate an empty repository class answer yes
4 Opening the Project with Netbeans
Open Netbeans.
- Select File\New Project
- Select PHP Application with Existing Sources.
- Click Next.
- On the New PHP Application with Existing Sources
- Select the source folder where you unzipped the Symfony framework (C:\NetbeansProjects\mroute_rest_service).
- Select PHP Version: 5.3
- Click Next
- Click Finish.
5 Connecting to the Database
5.1 Connection Parameters
On Netbeans open C:\NetbeansProjectsmroute_rest_service\app\config\parameters.ini.
Edit the connection parameters as shown:
[parameters]
database_driver = pdo_mysql
database_host = localhost
database_port =
database_name = gisroutes
database_user = root
database_password =
5.2 Making the One to Many Relationship work on the Entities
I had to figure out how to se the relationship using annotations. I found an example in XML and adapted it [1]. Another thing I found out was that I had to manually set the precision and scale of the decimal fields.
- Edit the Point.php and add the route
/**
* @ORM\ManyToOne(targetEntity="MRoute", inversedBy="points")
*/
private $route;
... - On the Point.php edit the $x adn $y Column definitio to add precision and scale as show:
/**
* @var decimal $x
*
* @ORM\Column(name="x", type="decimal", precision=10, scale=3)
*/
private $x;
/**
* @var decimal $y
*
* @ORM\Column(name="y", type="decimal", precision=10, scale=3)
*/
private $y; - Edit the MRoute.php and add the points
use Doctrine\Common\Collections\ArrayCollection;
...
class Route {
...
/**
* @ORM\OneToMany(targetEntity="Point", mappedBy="route")
* @var ArrayCollection $points
*/
private $points;
...
public function __construct() {git
$this->points = new ArrayCollection;
}
... - I found this cool hay to generate getters and setters [2]. The following command will create the getters and setters for the Point and Route entities.
php appconsole doctrine:generate:entities MyGISGISBundleEntity
5.3 Creating the Database and Tables
To create the database run:
php app/console doctrine:database:create
To create the tables run:
php app/console doctrine:schema:update --force
5.4 Generating CRUD Controllers and Templates (Optional)
As far as the web service is concerned you don´t need t create the CRUD controllers. I´m creating them to add data.
- On the command window run:
php .\app\console doctrine:generate:crud
- Fill like this:
The Entity shortcut name: MyGISGISBundle:MRoute
Do you want to generate the "write" actions [no]? yes
Configuration format (yml, xml, php, or annotation) [annotation]:
Routes prefix [/mroute]:
Do you confirm generation [yes]?
Confirm automatic update of the Routing [yes]?
Now we are ready to make our first test.
5.5 Viewing the Data on Apache
On Wamp´s Apache create an alias names route-rest-service pointing to C:\NetbeansProjects\mroute_rest_service.
Open a brower http://localhost/mroute-rest-service/web/app_dev.php/mroute/
6 Creating a RestFul Web Service
I found an example on how to configure the routing usting yml [3] and I adapted it to annotations.
What we want is to get a list of routes with their points in json format.
First thing we need to do is add a method that will fetch the entities from the database. The following code includes the pagination concept wich we will discuss on Part II.
- Open src\MyGIS\GISBundle\Entity\MRouteRepository.php
- Add the following code whitin the class
public function getMRoutes($order_by = array(), $offset = 0, $limit = 0) {
//Create query builder for languages table
$qb = $this->createQueryBuilder('m');
//Show all if offset and limit not set, also show all when limit is 0
if ((isset($offset)) && (isset($limit))) {
if ($limit > 0) {
$qb->setFirstResult($offset);
$qb->setMaxResults($limit);
}
//else we want to display all items on one page
}
//Adding defined sorting parameters from variable into query
if (isset($order_by)) {
foreach ($order_by as $key => $value) {
$qb->add('orderBy', 'l.' . $key . ' ' . $value);
}
}
//Get our query
$q = $qb->getQuery();
//Return result
return $q->getResult();
} - Open src\MyGIS\GISBundle\Controller\MRouteController.php
- Add the following code:
/**
* Deletes a MRoute entity.
*
* @Route("/routing-info/info.json", name="mroute_json_list")
* @Method("get")
*/
public function routingInfoAction() {
$page = 1;
$count = 25;
$em = $this->getDoctrine()->getEntityManager();
$mroutes = $em->getRepository('MyGISGISBundle:MRoute')->getMRoutes();
$r_array = $this->routes2Array($mroutes);
$r = array('page' => $page, 'count' => $count, 'routes' => $r_array);
return new Response(json_encode($r));
}
private function routes2Array($routes){
$routes_array = array();
foreach ($routes as $route) {
$points_array = array();
foreach ($route->getPoints() as $point){
$p_array = array('id' => $point->getId(), 'name' => $point->getName(),
'x' => $point->getX(),'y' => $point->getY(), 'ptype' => $point->getPType());
$points_array[] = $p_array;
}
$r_array = array('id' => $route->getId(), 'name' => $route->getName(), 'points' => $points_array);
$routes_array[] = $r_array;
}
return $routes_array;
} - You´ll have to add some data to the se the web service working. Since I haven´t figured out how to install the FixtureBundle from behind a proxy I add the data via sql using phpMyAdmin. Use the SQL in https://gist.github.com/1594781 to add data.
- Run http://localhost/mroute-rest-service/web/app_dev.php/mroute/routing-info/info.json from your browser and voila it works!!
7 References
[1] |
[2] | Databases and Doctrine ("The Model") http://symfony.com/doc/current/book/doctrine.html |
[3] | Routing http://symfpony-project.org/ |
Web services without WSDL?
ResponderEliminar