
Розробникам Symfony подобається, коли робота проста і красива, тому установка REST (відпочинок) це справа хвилин, якщо не потрібно спеціальних параметрів конфігурації. Однак, перш ніж ми перейдемо до технічної частини, давайте спершу зрозуміємо, що собою REST являє загалом.
Що таке REST?
Окрім бажання співати "No REST for the wicked!" ми повинні сказати, що REST дуже корисна річ у світі розробників.
Це програмне забезпечення Всесвітньої Мережі, архітектурний стиль якого допомагає зробити архітектуру високопродуктивною та легшою в супроводі з набором обмежень на проектування компонентів.
Навіщо використовувати REST?
Найперше, його використання забезпечує більш швидкий і більш ефективний спосіб розміщення необхідної інформації в Інтернеті. Візьмемо до прикладу книжкову полицю.
При застосуванні тут RESTful систему, щоб знайти третю книгу на полиці, його первинний ключ для блоку даних буде в URL - в нашому випадку, / книги / 3. Щоб отримати доступ до 29-ї сторінки цієї книги, вам потрібний URL / книги / 3 / Сторінка / 29.
1) Всі наші ресурси мають унікальні ідентифікатори (URL), що дає можливість сформулювати логічні запити, а структури URL-адрес, доступними для запитів.
2) Універсальність. Ви можете використовувати ті ж самі відповідні дані сервера, щоб повернутися до XML або JSON для обробки програмного забезпечення або загорнути в красивий дизайн для наочності.
3) REST це сервіс, який реалізує фактичну сервіс-орієнтовану архітектуру (SOA), архітектурний шаблон в дизайні комп'ютерного програмного забезпечення, в якому компоненти програми надають послуги іншим компонентам за допомогою протоколу обміну, як правило, через мережу.
3) Різна поведінка клієнтів відповідає однаковому коду;
4) Складний процес пошуку помилок у процесі розробки;
Класичний набір пакетів для Symfony & REST наступний:
Тим не менш, є ще більш простий спосіб зробити це:
Ця зв'язка встановлює FOSRestBundle, JMSSerializer і NelmioCorsBundle. Завантажити цей пакет і його залежності за допомогою композитора:
$ php composer.phar require voryx/restgeneratorbundle dev-master
Підключіть його до ядра програми:
public function registerBundles() { $bundles = array( //... new Voryx\RESTGeneratorBundle\VoryxRESTGeneratorBundle(), new FOS\RestBundle\FOSRestBundle(), new JMS\SerializerBundle\JMSSerializerBundle($this), new Nelmio\CorsBundle\NelmioCorsBundle(), //... ); //... }
І налаштуйте параметри конфігурації, як показано на картинці:
framework: csrf_protection: false #only use for public API fos_rest: routing_loader: default_format: json param_fetcher_listener: true body_listener: true #disable_csrf_role: ROLE_USER body_converter: enabled: true view: view_response_listener: force nelmio_cors: defaults: allow_credentials: false allow_origin: [] allow_headers: [] allow_methods: [] expose_headers: [] max_age: 0 paths: '^/api/': allow_origin: ['*'] allow_headers: ['*'] allow_methods: ['POST', 'PUT', 'GET', 'DELETE'] max_age: 3600 sensio_framework_extra: request: { converters: true } view: { annotations: false } router: { annotations: true }
Вуаля! Ви встановили REST у вашому проекті.
Тепер, щоб подивитися, що трапилося, ми створили Post Entity, на самому початку, що виглядав наступним чином:
<?php namespace AppBundle\Entity; use Doctrine\ORM\Mapping as ORM; /** * Post * * @ORM\Table() * @ORM\Entity */ class Post { /** * @var integer * * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ private $id; /** * @var string * @ORM\Column(name="name", type="string", length=255) */ private $name; /** * @var string * @ORM\Column(name="description", type="string", length=255) */ private $description;
Після того як ми зробили наш VoryxRestGeneratorBundle, ми створюємо контролер по:
php app/console voryx:generate:rest --entity="AppBundle:Post"
А ось те, що ми отримуємо в результаті:
Форми
<?php namespace AppBundle\Form; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolverInterface; class PostType extends AbstractType { /** * @param FormBuilderInterface $builder * @param array $options */ public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('name') ->add('description') ; } /** * @param OptionsResolverInterface $resolver */ public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults(array( 'data_class' => 'AppBundle\Entity\Post' )); } /** * @return string */ public function getName() { return 'appbundle_post'; } }
Створення посту
/**
* Create a Post entity.
*
* @View(statusCode=201, serializerEnableMaxDepthChecks=true)
*
* @param Request $request
*
* @return Response
*
*/
public function postAction(Request $request)
{
$entity = new Post();
$form = $this->createForm(new PostType(), $entity, array("method" => $request->getMethod()));
$this->removeExtraFields($request, $form);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $entity;
}
return FOSView::create(array('errors' => $form->getErrors()), Codes::HTTP_INTERNAL_SERVER_ERROR);
}
Дія «PUT»
/** * Update a Post entity. * * @View(serializerEnableMaxDepthChecks=true) * * @param Request $request * @param $entity * * @return Response */ public function putAction(Request $request, Post $entity) { try { $em = $this->getDoctrine()->getManager(); $request->setMethod('PATCH'); //Treat all PUTs as PATCH $form = $this->createForm(new PostType(), $entity, array("method" => $request->getMethod())); $this->removeExtraFields($request, $form); $form->handleRequest($request); if ($form->isValid()) { $em->flush(); return $entity; } return FOSView::create(array('errors' => $form->getErrors()), Codes::HTTP_INTERNAL_SERVER_ERROR); } catch (\Exception $e) { return FOSView::create($e->getMessage(), Codes::HTTP_INTERNAL_SERVER_ERROR); } }
Дія «PATCH»
/** * Partial Update to a Post entity. * * @View(serializerEnableMaxDepthChecks=true) * * @param Request $request * @param $entity * * @return Response */ public function patchAction(Request $request, Post $entity) { return $this->putAction($request, $entity); }
Дія «DELETE»
/** * Delete a Post entity. * * @View(statusCode=204) * * @param Request $request * @param $entity * @internal param $id * * @return Response */ public function deleteAction(Request $request, Post $entity) { try { $em = $this->getDoctrine()->getManager(); $em->remove($entity); $em->flush(); return null; } catch (\Exception $e) { return FOSView::create($e->getMessage(), Codes::HTTP_INTERNAL_SERVER_ERROR); } }
Цей матеріал був підготовленний для конференції PHP Frameworks Day 2015 і презентований Олексієм Веркеєнко, розробником з компанії Grossum (www.grossum.com). Оригінал статті - http://www.grossum.com/blog/rest-api-symfony2-setting-it-up-in-minutes