18 октября 2014 в 02:26

Простой каркас Rest Api на основе Phalcon

PHP*
Привет всем.
Вот хочу предложить небольшой пример реализации простого rest api на основе популярного фреймвокра Phalcon. Даже фаткически не реализацию, а её каркас. Сразу уточню что статья расчитана на новичков. Людей обознанных и опытных врядли заинтересует содержимое.
Phalcon предоставляет широкие возможности для разработки, а также очень большую свободу для творчества и создания хороших продуктов, потому пример действительно очень прост.

Фактически всё что надо — лишь создать конкретный экшн в контроллере, цель которого сделать return набора нужных данных, при этом роутинг строится на основе аннотаций к конкретному экшену, пример:
<?php

namespace RestApi\Api\Controllers;

class IndexController extends RestController
{

    /**
     * @Get("/get")
     */
    public function getAction()
    {
        return ['getAction'];
    }

    /**
     * @Post("/post")
     */
    public function postAction()
    {
        $this->setStatusCode(201);
        return ['postAction'];
    }

    /**
     * @Put("/put")
     */
    public function putAction()
    {
        $this->setStatusCode(201);
        return ['putAction'];
    }

    /**
     * @Delete("/delete")
     */
    public function deleteAction()
    {
        return ['deleteAction'];
    }

}

Что значит: URI /get доступен для GET запросов, /post для Post и тд. Ответ возвращает json представление значения, которое вернет экнш контроллера. Уточню что api поддерживает лишь json формат вывода, в то же время очень просто добавить новый лишь расширив метод RestController::prepareResponse.
Роутинг построен на аннотациях и поддерживает целый ряд форматов, которые можно найти тут.
Создавая новый конроллер, его необходимо пронаследовать от базового RestController и добавить описание в /config/ruotes.php:
$router->addModuleResource("api", "RestApi\Api\Controllers\NewController");

Вот собственно и все!
Исходники находятся здесь. Большое спасибо за внимание и просьба не судить строго. Если даже никому и не пригодится реализация, возможно статья возбудит интерес к самому фреймворку, а он действительно крут.
Евгений @Jackson88
карма
5,0
рейтинг 0,0
Похожие публикации
Самое читаемое Разработка

Комментарии (13)

  • 0
    Хотелось бы больше услышать про парсер аннотаций и маршрутизатор аннотаций: в чем профит, подводные камни и т.д.

    Сейчас статья выглядит как «наткнулся на аннотации, смотрите как можно делать».
    • 0
      Сейчас статья выглядит как «наткнулся на аннотации, смотрите как можно делать».

      Статья Пост про реализацию REST или даже больше привлечение внимания к Phalcon
      Профит аннотаций очевиден: роутинг описан рядом с action-ом сразу можно сопоставить с action и url.
      Камни: Сложнее выявить неоднозначность роутинга и необходимость парсить/кэшировать.
      • 0
        Да, именно пост. И цель его Вы описали куда лучше чем я. Вообщем, спасибо Вам за такой комментарий!
    • 0
      На самом деле всё не совсем так — лично мне просто очень импонирует то, что экшн контроллера лишь возвращает набор данных, а не создает, к примеру, объект респонса и делает что-то вроде echo или обертку над echo в ввиде send() в самом экшене, или же, как часто можно встретить в примерах реализаций подобное: echo json_encode($result);. Можно писать очень тонкие контроллеры, без дублирования стандартных операций, всю логику вынося, скажем, на сервиса.
      А касательно роутинга — то это достаточно крутая возможность, которую, в тоже время, можно заменить на стандартную Phalcon\Mvc\Router, разграничив достпуп по типам http запросов в виде конфига, например:
      $routes->addGet('/get');
      $routes->addPost('/post');
      

      При этом слегка ухудшив понятность кода, потому как, я думаю, Вы не будет спорить что с аннотациями код будет выглядеть как минимум красивее.
      На счет профита и подводных камней. Собственно профит, как я уже написал выше, в совмещении функционала и красоты. А вот подводных камней, теоретически, они могут быть — Phalcon это расширение, продебажить реализацию не просто(разве в сишных исходниках), чтобы с уверенностью сказать что там все хорошо.
      Парсинг основан не на, де-факто, стандартном подходе с Reflection, а на собственной с-шной реализации, работающей значительно быстрее Reflection + из коробки есть возможность кеширования результатов парсинга (например, Phalcon\Annotations\Adapter\Files для хранения результата в файле)
      • –1
        Вот мне интересно, почему аннотации записываются в блоке комментариев, а не как декораторы в питоне — непосредственно перед функцией. Ведь если по какой-то причине не распарсятся — это будет неверная логика приложения. А если их описывать не в закомментированном виде, а в явном — приложение не запустится, что будет значить примерно одно и то же. Ведь у них все равно есть отдельный парсер, который не завязан не Reflection
        example
        /*
        * @annotation
        */
        funciton getList() {}
        
        против
        
        @annotation
        function getList() {}
        
        

        • 0
          Думаю просто потому что php к этому еще к этому не пришел (а может и не прийдет). Аннотации не являются встроенными возможностями языка, потому и приходим к их реализации через комментарии.
          • –1
            Это понятное дело. Я про то, что покуда они все равно парсятся препроцессором в том или ином виде, а если он не отработает — приложение будет отрабатывать неправильно, почему сразу не сделать так. Ведь если препроцессор не отработает в текущем виде — приложение запустится, но будет неправильно функционировать. Если сделать как я предлагаю — оно даже не запустится, что будет однозначно (по первой же ошибке) указывать на то, что не сработало. Ну и синтаксически красивее. Единственное, поддержка в IDE будет никакой, но если они и сейчас не поддерживают аннотации — это все равно не удобно.
            Но это лично мое ИМХО и хотелось бы узнать, почему внедряют расширения языка именно в виде комментариев? Причем, так делает не только Phalcom. Это связано с тем, как работают предкомпиляторы? Т.е. они после загрузки файла через рефлексию изменяют код или есть другие причины?
            • +1
              Достаточно не простой вопрос, и подобные предложения не раз рассматривались собcтвенно разработчиками php. Видимо к единному стандарту они не пришли или же отложили эту тему. Собственно также важно понимать принцип работы интерпритатора — сперва происходит парсинг, выявить на этом этапе не синтакисческие ошибки не получится, после код уже интерпретируется в исполнимый байткод. Если аннотации добавить как структуры языка с определенными ключевыми словами — можем получать parse error при некорректом использовании, уже на этапе парсинга, но думаю список таких зарезервированных лексем языка может быть крайне большим и потеряет свой смысл. Думаю кроме такого варианта нет возможности выявить не на этапе выполнения. Конечно было бы очень не плохо даже на этапе выполнения получить к примеру E_STRICK при несоответствии аннотации содержимому метода (или как-нибудь иначе). Собственно php любой тип ошибок, связанный с выполнимым кодом, кроме parse error выявляет уже на этапе его выполнения(E_COMPILE и E_CODE не в счет, это ошибки другого характера).
              • 0
                Хм. Не, питон мне не сильно нравится, но вот идея декораторов прям очень нравится (сейчас в голове живет идея сделать некий аналог для js, там такое реализовать не сложно, в ноде, например, попросту расширить require, который перед исполнением модуля еще парсер запустит). Такая идея позволит самому свободно дописывать декораторы. Собственно, в php можно поступить аналогичным образом. Использовать не include(), а свою функцию, которая будет аналогом require в ноде. Т.е. он открывает файл, парсит его на наличие декораторов, вызывает функции обработки декораторов (очевидно, они должны быть объявлены заранее), в случае, если обнаружен необъявленный декоратор — вызывается ошибка времени исполнения (покуда я предлагаю путь не изменения самого языка, а дописывание), затем оборачивает код в модуль и исполняет его как функцию. Эдакий AMD подход на php. Но, наверное, там это излишки.

                Но такой подход позволит одним кликом экспортировать роуты, организовывать тесты REST API (подменяя аннотации, хотя это возможно и сейчачс), да и… Похоже, у меня node.js головного мозга.
  • +2
    deniskin, вы сломали Хабр. Количество «странных» публикаций увеличилось :(
    • –2
      «Странными» публикациями вы считаете относящиеся к IT?
  • +1
    Наследовать контроллеры REST приложения от Phalcon\Mvc\Controller — не самая лучшая затея, MVC стек у нас сделан для MVC приложений, с накладываемым overhead на view и другие необходимые зависимости и сервисы.

    Для большей скорости, простоты и именно реализации REST стоит присмотреться к Phalcon\Mvc\Micro ( docs.phalconphp.com/en/latest/reference/micro.html )
  • 0
    Я никогда не работал с Phalcon, непонятно что возвращают эти методы: XML, JSON, HTML? Как это настраивать?

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