REST API & Symfony2: Швидке налаштування (Налаштування за лічені хвилини)

02/12/2015 0 symfony, налаштування, конфігурація

Розробникам Symfony подобається, коли робота проста і красива, тому установка REST (відпочинок) це справа хвилин, якщо не потрібно спеціальних параметрів конфігурації. Однак, перш ніж ми перейдемо до технічної частини, давайте спершу зрозуміємо, що собою REST являє загалом.

Що таке REST?

Окрім бажання співати "No REST for the wicked!"  ми повинні сказати, що REST дуже корисна річ у світі розробників.

Це програмне забезпечення Всесвітньої  Мережі, архітектурний стиль якого допомагає зробити архітектуру високопродуктивною  та легшою в супроводі з набором обмежень на проектування компонентів.

Навіщо використовувати REST?

Найперше, його використання забезпечує більш швидкий і більш ефективний спосіб розміщення необхідної інформації в Інтернеті. Візьмемо до прикладу книжкову полицю.

При застосуванні тут RESTful систему, щоб знайти третю книгу на полиці, його первинний ключ для блоку даних буде в URL - в нашому випадку, / книги / 3. Щоб отримати доступ до 29-ї сторінки цієї книги, вам потрібний URL  / книги / 3 / Сторінка / 29.

Переваги використання REST в наших проектах:

1) Всі наші ресурси мають унікальні ідентифікатори (URL), що дає можливість сформулювати логічні запити, а структури URL-адрес, доступними для запитів.

2) Універсальність. Ви можете використовувати ті ж самі відповідні дані сервера, щоб повернутися до XML або JSON для обробки програмного забезпечення або загорнути в красивий дизайн для наочності.

3) REST це сервіс, який реалізує фактичну сервіс-орієнтовану архітектуру (SOA), архітектурний шаблон в дизайні комп'ютерного програмного забезпечення, в якому компоненти програми надають послуги іншим компонентам за допомогою протоколу обміну, як правило, через мережу.

Що потрібно пам’ятати (або проблеми використання):
1) Відсутність взаємної згоди і стандартизації;
2) Часткова підтримка відповідних заголовків;

3) Різна поведінка клієнтів відповідає однаковому коду;

4) Складний процес пошуку помилок у процесі розробки;

Як його встановити в SYMFONY?

 

Класичний набір пакетів  для Symfony & REST наступний:

1) FOSRestBundle

2) JMSSerializer

3)NelmioApiDocBundle

Тим не менш, є ще більш простий спосіб зробити це:

1)VoryxRestGeneratorBundle

Ця зв'язка встановлює 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

Поділитися