Как создать REST API в Phalcon
В этой заметке рассматривается отправка и получение данных с помощью REST API. Рассматривается две задачи отдельно:
Документация - хорошо, а примеры никогда лишними не бывают. Итак, есть работающее веб-приложение, в котором созданы модели и контроллеры для обработки данных. Например, есть модель Sotrudniki с данными о сотрудниках.
Организация ответа на запрос с другого ресурса
Для этого необходимо создать новый контроллер. Например, ApiController.php с классом ApiController. В контроллере создать функцию подготовки и выдачи запрашиваемых данных. Данные о сотрудниках передадим только id и place.
Файл ApiController.php
// используется модель Sotrudniki use Vokuro\Models\Sotrudniki; class ApiController extends ControllerBase { public function sotrudnikiAction(){ // чтение данных из таблицы Sotrudniki $sotrudniki = Sotrudniki::find (); $data = []; // помещение необходимых полей/данных в массив foreach ($sotrudniki as $sotrudnik) { $data[] = [ 'id' => $sotrudnik->id, 'place' => $sotrudnik->place, ]; } // перевод массива в строку json return json_encode($data); } }
Стороннему ресурсу данные будут доступны по адресу https://ВАШ.ДОМЕН/api/sotrudniki/ в формате json. Пример: [{"id":"1","place":"112"},{"id":"2","place":"111"},{"id":"3","place":"113"},{"id":"4","place":"114"},{"id":"5","place":""}].
Для выдачи только строки из таблицы Sotrudniki по id создается функция sotrudnikiid в этом классе.
public function sotrudnikiidAction($id){ $sotrudnik = Sotrudniki::findFirstById($id); $data = []; $data[] = $sotrudnik->id; $data[] = $sotrudnik->place; echo json_encode($data); }
Стороннему ресурсу данные будут доступны по адресу https://ВАШ.ДОМЕН/api/sotrudnikiid/id/ в формате json. Вместо id в конце указать запрашиваемое значение. На запрос https://ВАШ.ДОМЕН/api/sotrudnikiid/1/ будут получены данные об одном сотруднике с id=1: [{"id":"1","place":"112"}]
Организация запроса данных с другого ресурса
Для этого необходимо создать новый контроллер. Например, ApirequestController.php с классом ApirequestController. В контроллере создать функцию запроса и обработки полученных данных. Если данные предполагается выводить на страницу, то создаем шаблон с именем функции sotrudniki.volt с папкой apirequest в корневой папке views.
Файл ApirequestController.php
class ApirequestController extends ControllerBase { public function sotrudnikiAction() { // подключение шаблона $this->view->setTemplateBefore('public'); $resource = 'sotrudniki/'; $method = 'GET'; define("BASE_URL", "https://ЧУЖОЙ.ДОМЕН/api/"); $full_url = BASE_URL . "$resource"; $options = array( CURLOPT_URL => $full_url, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => array('Content-Type: application/json', 'Accept: application/json'), CURLOPT_CUSTOMREQUEST => $method ); $ch = curl_init(); curl_setopt_array($ch, $options); $out = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ( $status > 399 ) { throw new Exception("Exception $status: $out"); } // декодирование в ассоц массив $content = json_decode($out, true); // вывод в шаблон $this->view->sotrudniki = $content; } }
Функция отправит запрос https://ЧУЖОЙ.ДОМЕН/api/sotrudniki/ на ресурс ЧУЖОЙ.ДОМЕН для получения данных об их сотрудниках. Ответ придет в формате json. Пример: [{"id":"1","place":"112"},{"id":"2","place":"111"},{"id":"3","place":"113"},{"id":"4","place":"114"},{"id":"5","place":""}].
В шаблоне развернем данные. Файл sotrudniki.volt
{{ content() }} <h2 class="pager">Сотрудники</h2> <table class="table table-bordered table-striped" align="center"> <thead> <tr class="header_table"> <th>Сотрудник</th> <th>Место</th> </tr> </thead> <tbody> <?php foreach ($sotrudniki as $value) { echo '<tr>'; foreach ($value as $k => $v) { echo '<td>' .$v. '</td> '; } echo '</tr>'; } ?> </tbody> </table>
Шифрование данных
Чтобы защитить данные от излишних несанкционированных запросов и перехватов в процессе передачи, можно прибегнуть к одному из способов шифрования данных.
Для этого воспользуемся компонентом Phalcon\Crypt.
Файл ApiController.php будет выглядеть следующим:
// используем компонент Crypt use Phalcon\Crypt; use Vokuro\Models\Sotrudniki; class ApiController extends ControllerBase { public function sotrudnikiAction(){ $sotrudniki = Sotrudniki::find (); $data = []; foreach ($sotrudniki as $sotrudnik) { $data[] = [ 'id' => $sotrudnik->id, 'place' => $sotrudnik->place, ]; } $dataString = json_encode($data); // кодирование строки с данными $dataString $crypt = new Crypt(); $crypt->setCipher('aes-256-ctr'); // ключ для шифрования $key = "T4\xb1\x8d\xa9\x98\x05\x6y\hdl\x8c\xbe\x1d\x07&[\x99\x18\xa4~Lc1\xbeW\xb3"; $encrypted = $crypt->encrypt($dataString, $key); return $encrypted; } }
Файл ApirequestController.php будет выглядеть следующим:
use Phalcon\Crypt; public function sotrudnikiAction() { $this->view->setTemplateBefore('public'); $resource = 'sotrudniki/'; $method = 'GET'; define("BASE_URL", "http://ЧУЖОЙ.ДОМЕН/api/"); $full_url = BASE_URL . "$resource"; $options = array( CURLOPT_URL => $full_url, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => array('Content-Type: application/json', 'Accept: application/json'), CURLOPT_CUSTOMREQUEST => $method ); $ch = curl_init(); curl_setopt_array($ch, $options); $out = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ( $status > 399 ) { throw new Exception("Exception $status: $out"); } // раскодирование полученной строки $out $crypt = new Crypt(); $crypt->setCipher('aes-256-ctr'); $key = "T4\xb1\x8d\xa9\x98\x05\x6y\hdl\x8c\xbe\x1d\x07&[\x99\x18\xa4~Lc1\xbeW\xb3"; $sotr = $crypt->decrypt($out, $key); $content = json_decode($sotr, true); // true - декодирование в ассоц массив $this->view->sotrudniki = $content; }
Ключ шифра придумайте сами, он должен находиться на обоих ресурсах.
Об алгоритмах шифрования подробнее здесь.