Создание простого REST-приложения на Silex

Автор оригинала: David Makin
  • Перевод
В этой статье мы создадим простое REST приложение на PHP-фреймворке Silex, начав с установки Silex и закончив созданием нескольких маршрутов приложения.
Silex — это PHP микро-фреймворк от создателей Symfony и во многом построенный на его базе. Подробнее о нем можно узнать из следующего хабрапоста


Давайте начнём


Для этого примера я буду использовать каталог с именем toyshop

Установка Silex


Есть несколько способов установки Silex, но давайте используем для этого Composer.
Внутри вашей рабочей директории выполните команду:

composer require silex/silex ~1.1


С помощью этой команды вы дали команду Composer сделать следующее:
  • require добавляет новый пакет к проекту
  • silex / silex имя пакета в формате поставщик(vendor)/пакет(package)
  • ~ 1.1 — версия пакета, ~ 1.1 означает >= 1.1, <2,0


Когда Вы запустите эту команду, Вы увидите, что Composer установит также и библиотеки, которые Вы не запрашивали, — не волнуйтесь, так и должно было произойти, так как Silex требует наличия этих библиотек, для корректной работы.

Как только команда закончит выполнение, вы получите следующую файловую структуру, приведённую ниже:
toyshop/
       composer.json
       composer.lock
       vendor/
             ...


Весь код Silex хранится внутри папки vendor, а 2 файла Composer'a содержат информацию о том, какие пакеты и версии библиотек установлены.

Composer.json


Давайте посмотрим внутрь composer.json, он должен выглядеть примерно так:
{
    "require": {
        "silex/silex": "~1.1"
    }
}


Composer.lock


Этот файл содержит список всех установленных пакетов, а также их версии. Это очень полезно, поскольку это означает, что Вы теперь не должны делать commit папки vendor/, когда заливаете проект в репозиторий — все библиотеки, необходимые для корректной работы приложения, могут быть установлены на основе этого файла. Вам лишь необходимо залить в репозиторий файлы composer.json и composer.lock и тогда, как только код будет извлечен из репозитория, Вы можете просто запустить команду composer install и Composer сам установит необходимые библиотеки указанных версий.

Создание маршрутов



Так как наше приложение — это магазин игрушек, давайте подумаем, что нам будет нужно. Люди, которые будут заходить на наш сайт, захотят увидеть подарки, значит давайте создадим маршрут, который позволит получить список подарков.

Давайте создадим файл index.php. Добавим в него код, чтобы он выглядел следующим образом:
<?php
 require_once __DIR__.'/vendor/autoload.php';
  
 $app = new Silex\Application();
 // Please set to false in a production environment
 $app['debug'] = true;
 
 $toys = array(
     '00001'=> array(
        'name' => 'Racing Car',
        'quantity' => '53',
        'description' => '...',
        'image' => 'racing_car.jpg',
    ),
    '00002' => array(
        'name' => 'Raspberry Pi',
        'quantity' => '13',
        'description' => '...',
        'image' => 'raspberry_pi.jpg',
    ),
);

$app->get('/', function() use ($toys) {
    return json_encode($toys);
});

$app->get('/{stockcode}', function (Silex\Application $app, $stockcode) use ($toys) {
    if (!isset($toys[$stockcode])) {
        $app->abort(404, "Stockcode {$stockcode} does not exist.");
    }
    return json_encode($toys[$stockcode]);
});

$app->run();


Теперь у нас объявлено 2 маршрута: / и /{stockcode}

Маршрут /


Это маршрут для получения списка всех игрушек. Все, что делает данный метод — это кодирует данный в JSON и возвращает закодированные данные в качестве ответа на запрос.

Чтобы разрешить анонимной функции доступ к массив $toys мы должны импортировать его, добавив use($toys) в конце определения анонимной функции, но до открытия скобки {.

Маршрут /{stockcode}


Это маршрут для получения информации о конкретной игрушке, которая идентифицируется параметром stockcode. Как Вы видете, что это в этом маршруте используется функция с чуть более сложным заголовком.

Наряду с use($toys) мы передаем пару переменных в саму функцию: Silex\Application $app и $stockcode.

Silex\Application $app — это объект приложения Silex и с его помощью мы можем вывести красивую страницу ошибки 404, если был передан неверный stockcode.

$stockcode — идентификатор игрушки, информацию о которой мы хотим получить. Как Вы видете, эта переменная соответствует {stockcode}, который есть в описанном нами маршруте.

Тестируем приложение



После настройки веб-сервера для маршрутизации всех запросов через index.php можно перейти к маршрутам с помощью toyshop и toyshop/00001 и увидеть результат, который вернёт каждый из этих запросов.

Например, toyshop/00001 вернёт:
{"name":"Raspberry Pi","quantity":"13","description":"...","image":"raspberry_pi.jpg"}


Ответ возвращает в удобном формате, подходящем для использования в Вашем интернет-магазине или мобильном приложений. Всё, что надо сделать, это выполнить над этими данными функцию json_decode и отобразить данные в удобном формате, например, HTML.

Почему Silex?


Хороший вопрос.
Ответ: поскольку это микро-фреймворк, он не заставляет меня писать в своём ​​собственном предпочтительном стиле и выходит мне не нужно менять свой стиль программирования, чтобы работать с Silex. Если бы Вы хотели, Вы могли бы использовать Slim, любой другой микро-фреймворк или даже полноценные фреймворки как Symfony или Zend.

Примечания от переводчика


Хотелось бы добавить, что также легко работать в Silex и с другими типами HTTP-запросов, такими, как PUT, POST, DELETE (пример ниже)
$app->post('/toys', function (Silex\Application $app) use ($toys) {
   //...
});

$app->put('/{stockcode}', function (Silex\Application $app, $stockcode) use ($toys) {
   //...
});

$app->delete('/{stockcode}', function (Silex\Application $app, $stockcode) use ($toys) {
   //...
});


Таким образом можно создать полноценное REST-приложение.
Поделиться публикацией

Комментарии 15

    +1
    по опыту создания REST бекенда скажу, что мало нормально реагировать на GET/POST/PUT/DELETE.
    самая сложная задача как мне кажется — это сериализация данных. Конечно, можно начинать на микрофреймворке, но затем вам всё равно понадобится доменная модель (читай доктрина), потом сериализатор (читай JMS) и внезапно о легковесности приложения можно забыть.
      0
      вот как раз в случаях большого роста сложности REST-приложения со временем, как мне кажется, Silex себя показывает с хорошей стороны, поскольку он построен на базе Symfony и может легко использовать все компоненты Symfony, ту же доктрину и тд. И в итоге можно из него будет собрать мощный фреймворк
        0
        В итоге получится тот же Symfony)
          0
          И что в этом плохого? Что бы получился SYmfony нужно еще DependencyInjection и Config подключить, еще нужно реализовать систему кеширования всего этого дела, систему бандлов и т.д.

          Silex это демонстрация основного принципа Symfony — разделение на компоненты, модульность. Хочешь используй это, хочешь то…
            0
            Я не говорил что это плохо.

            И еще в Silex есть DI)
              +2
              в silex нет DI. Есть service locator
                0
                Pimple все же не дотягивает до статуса контейнера зависимостей.
          +1
          Используем Silex на паре проектов. В купе с Doctrine, JMS Serializer и т.д. Никаких проблем с тем что нету из коробки системы бандлов не наблюдалось. Для небольших API сервисов более чем подходит.
          0
          Перевод слабенький, много отсебятины (смотря на заголовок «тестируем ***» я ожидаю увидеть пояснение как покрыть нашу API функциональными тестами.

          Вообще не понятно для кого статья. Люди не работавшие в плотную с Silex не узнают в чем плюсы, люди использующие Silex сделают фейспалм видя примеры кода и пойдут дальше.
            +1
            спасибо за мнение
            за отсебятину извиняюсь, буду исправляться

            вообще оригинальный пост был взят из последнего дайджеста по PHP и переведен для того, чтобы человек, ищущий информацию по запросу «REST PHP» и не знающий какой фреймворк ему лучше использовать, увидел статью, увидел кратенький пример как работать с HTTP маршрутами

            а много дополнительной полезной информации как часто это бывает, он бы уже узнал из комментариев к посту :)
            0
            Хотелось бы в шапке видеть информацию про то, что такое Silex и что, в общем-то, дело касается PHP (нет, в RSS этого не видно).
              +1
              спасибо за замечание
              подправил и добавил ссылку на хабропост о Silex
              0
              Зачем json_decode/encode когда есть $app->json()
                0
                по правде говоря на этот вопрос однозначно может ответить только сам автор, но от себя предположу следующее:
                1) автор решил не запутывать пользователей, только знакомящихся с Silex и решил использовать всем привычный json_encode (хотя конечно лучше бы было приучивать сразу к написанию в едином стиле)
                2) автор по-просту в спешке забыл о существовании $app->json

                я же как переводчик решил оставить код как есть, но спасибо за замечание
                  0
                  это нормально, потому как потом можно заменить на $app['serializer']->serialize($data, 'json').

              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

              Самое читаемое