Мы привыкли почему-то разделять REST и RPC, мне кажется это разделение искусственным. Просто REST строже и ограничен в методах, и это не всегда оправдано в сложном приложении.

Сделаем простую основу для написания сервисно-ориентированной архитектуры. Как стек технологий используем славный Yii2, быстрый Nginx и молниеносный Redis. Почему именно так, станет ясно позднее.

Для управления сущностями на примитивном уровне СREATE, UPDATE, DELETE, GET нам вполне достаточно Rest техники которая заложена в Yii2.

Для облегчения работы в сцепке Nginx + Redis, нам придется использовать немного нестандартный подход, то есть полностью передать как параметры: класс, метод и другие нужные параметры. Для валидации этой компании используем наипростейшую форму Yii2 Model (для экономии места проигнорируем code style):

class QueryForm extends Model
{
   /**
    * @properties for REST
    */    
   public $restModel = '';  // Class
   public $restMethod = ''; // Method
   public $restId = null;   // Rest id модели 
   public $restAttributes = []; // аттрибуты модели 
   /**
    * @properties for RPC
    */
   public $categories = []; // фильтр по типу места
   public $tags = [];  // Теги для запроса
   public $match = ''; //  запрос по фразе
   public $cache = 1; // флаг кеширования
//  ну и так далее ... 

Дальше соответственно валидация всей этой веселой компании, тут очевидно, надеюсь.

Nginx при определенных условиях (если нужны дополнительные модули — ссылка ниже) может перехватить ссылку, послать запрос в Redis, и если Redis по ключу ничего не найдет, то поднимем PHP Yii2, который методом actionCall подготовит ответ и запишет его в кеш (работающий на основе того же Redis).

$params = $this->getEncodeParams($key);

$query = new \common\models\QueryForm();

if ($query->validateParams($params)) {

   $this->setHeader(self::CODE_OK, self::MSG_OK);

   $this->setData($this->callDispatcher($query));
} 
else {

   $this->setHeader(self::CODE_ERROR, self::MSG_INPUT_PARAMETER_ERROR
 . print_r($query->getErrors(), true));

}

$this->response();

Схематично диспечер callDispatcher, который обрабатывает REST и RPC:

1) Cначала запросы по ID: POST, GET, DELETE, CREATE (тут все просто благодоря Yii2).

2) Ну и наконец после этого в диспетчере обработаем запросы всех сущностей RPC, необходимых вашему приложению.

Что у нас в итоге:

— единый метод класса actionCall ($key), который обработает любой запрос REST и RPC.
— keуParams — универсальный закодированный ключ, который подходит для получения ответа сервиса, используя сцепку Nginx + Redis (за подробностями вам сюда), минуя PHP, и одновременно он подходит для обработки запроса используя PHP FM Yii2.

Если вам кажется, что будет неудобно работать с такими ссылками (url), то это не совсем так, немного смекалки — и все у вас будет очень даже удобно. Некоторые уже совсем очевидные вещи сознательно опущены.

Всем удачи, коллеги!

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


  1. lair
    08.02.2016 13:30
    +2

    Мы привыкли почему-то разделять REST и RPC, мне кажется это разделение искусственным.

    А зря. У REST и RPC принципиально разные подходы.

    Просто REST строже и ограничен в методах, и это не всегда оправдано в сложном приложении.

    «Строже и ограничен»? Ровно наоборот: все RPC-шные «выполни метод» соответствуют одному REST-овскому POST.