Hello,
As a symfony freelance, We still need to interface our sites with others. To do this we often use API (Applications Programming Interface).
From lasts posts, We explained to you what is a API and the two main methods to develop them in PHP : REST et SOAP.
Here we go further by showing you how to create a REST API with PHP and framework Symfony 3 !!!
To get to the simplest, we assume that you have a web server properly configured with Composer installed et fonctionnal.
To start, you need to install the Symfony framework:
# From you appache root directory or vhost.
composer create-project symfony/framework-standard-edition example "3.3.*"
This command line will be used to download and install the framework in the example directory.
Then we will use two bundles essential to our application :
composer require jms/serializer-bundle
composer require friendsofsymfony/rest-bundle
We need to create our own bundle :
cd example
php bin/console generate:bundle
php bin/console doctrine:create:database
We imagine making this entity on this API :
# src/ExampleBundle/Resources/config/doctrine/weenesta_user.orm.yml
ExampleBundle\Entity\WeenestaUser:
type: entity
table: weenesta_user
id:
id:
type: integer
generator: { strategy: AUTO }
fields:
name:
type: string
length: 100
Your own Bundle is configured to use the FOS Rest bundle :
#app/config/config.yml
fos_rest:
format_listener:
rules:
- { path: '^/weenestauser', priorities: ['xml', 'json'], fallback_format: xml, prefer_extension: true }
- { path: '^/', priorities: [ 'text/html', '*/*'], fallback_format: html, prefer_extension: true }
We generates the entity from doctrine :
php bin/console doctrine:generate:entity WeenestaUser
php bin/console doctrine:schema:update --force
We creates controller :
#src/ExampleBundle/Controller/WeenestaUserController.php
namespace ExampleBundle\Controller;
use FOS\RestBundle\Controller\FOSRestController;
use Symfony\Component\HttpFoundation\Request;
use FOS\RestBundle\Controller\Annotations\Get;
use FOS\RestBundle\Controller\Annotations\Post;
use FOS\RestBundle\Controller\Annotations\Delete;
use ExampleBundle\Entity\WeenestaUser;
class WeenestaUserController extends FOSRestController
{
/**
* findWeenestaUserByRequest
*
* @param Request $request
* @return WeenestaUser
* @throws NotFoundException
*/
private function findWeenestaUserByRequest(Request $request) {
$id = $request->get('id');
$user = $this->getDoctrine()->getManager()->getRepository("ExampleBundle:WeenestaUser")->findOneBy(array('id' => $id));
return $user;
}
/**
* validateAndPersistEntity
*
* @param WeenestaUser $user
* @param Boolean $delete
* @return View the view
*/
private function validateAndPersistEntity(WeenestaUser $user, $delete = false) {
$template = "ExampleBundle:WeenestaUser:example.html.twig";
$validator = $this->get('validator');
$errors_list = $validator->validate($user);
if (0 === count($errors_list)) {
$em = $this->getDoctrine()->getManager();
if ($delete === true) {
$em->remove($user);
} else {
$em->persist($user);
}
$em->flush();
$view = $this->view($user)
->setTemplateVar('user')
->setTemplate($template);
} else {
$errors = "";
foreach ($errors_list as $error) {
$errors .= (string) $error->getMessage();
}
$view = $this->view($errors)
->setTemplateVar('errors')
->setTemplate($template);
}
return $view;
}
/**
* newWeenestaUserAction
*
* @Get("/weenestauser/new/{name}")
*
* @param Request $request
* @return String
*/
public function newWeenestaUserAction(Request $request)
{
$user = new WeenestaUser();
$user->setName($request->get('name'));
$view = $this->validateAndPersistEntity($user);
return $this->handleView($view);
}
/**
* editWeenestaUserAction
*
* @Get("/weenestauser/edit/{id}/{name}")
*
* @param Request $request
* @return type
*/
public function editWeenestaUserAction(Request $request) {
$user = $this->findWeenestaUserByRequest($request);
if (! $user) {
$view = $this->view("No WeenestaUser found for this id:". $request->get('id'), 404);
return $this->handleView($view);
}
$user->setName($request->get('name'));
$view = $this->validateAndPersistEntity($user);
return $this->handleView($view);
}
/**
* deleteWeenestaUserAction
*
* @Get("/weenestauser/delete/{id}")
*
* @param Request $request
* @return type
*/
public function deleteWeenestaUserAction(Request $request) {
$user = $this->findWeenestaUserByRequest($request);
if (! $user) {
$view = $this->view("No WeenestaUser found for this id:". $request->get('id'), 404);
return $this->handleView();
}
$view = $this->validateAndPersistEntity($user, true);
return $this->handleView($view);
}
/**
* getWeenestaUserAction
*
* @Get("/sweenestausers")
*
* @param Request $request
* @return type
*/
public function getWeenestaUserAction(Request $request) {
$template = "ExampleBundle:WeenestaUser:example.html.twig";
$users = $this->getDoctrine()->getManager()->getRepository("ExampleBundle:WeenestaUser")->findAll();
if (0 === count($users)) {
$view = $this->view("No WeenestaUser found.", 404);
return $this->handleView();
}
$view = $this->view($users)
->setTemplateVar('users')
->setTemplate($template);
return $this->handleView($view);
}
}
We create Twig template :
#src/ExampleBundle/Resources/views/WeenestaUser.html.twig
{% if errors is defined %}
{{ errors }}
{% else %}
{% if users is defined %}
{{ users | serialize }}
{% else %}
{{ user | serialize }}
{% endif %}
{% endif %}
And voila, you have created your first API with symfony framework !
You can get full source code from GitHub.
Your can access it from your web server...
See you soon,
Mathieu