БЛОГ

Как создать 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;
    }

 Ключ шифра придумайте сами, он должен находиться на обоих ресурсах.

Об алгоритмах шифрования подробнее здесь.

Бекет
Полезная статья!
Ответить | Ответить с цитатой
05.08.2021 18:28

Добавить комментарий


ОБРАТНЫЙ ЗВОНОК
Заполните форму и наш менеджер Вам перезвонит