REST API
API — набор адресов, по которым с сайтом общается не человек, а программа: мобильное приложение или скрипт в браузере. REST — договорённость о таких адресах: GET /posts возвращает список, POST /posts создаёт запись, DELETE /posts/5 удаляет. В Yii готовый API для модели даёт класс yii\rest\ActiveController.
Контроллер API
Чтобы не смешивать API со страницами сайта, контроллер кладут в подпапку. Создайте вручную папку controllers/api и файл в ней:
// controllers/api/PostController.php
namespace app\controllers\api;
use yii\rest\ActiveController;
class PostController extends ActiveController
{
public $modelClass = 'app\models\Post';
}Больше кода не нужно: действия для списка, просмотра, создания, изменения и удаления уже есть в ActiveController. Маршрут контроллера из подпапки — api/post.
Правило адресов
Добавьте в rules компонента urlManager в config/web.php:
// config/web.php
'rules' => [
['class' => 'yii\rest\UrlRule', 'controller' => 'api/post'],
// остальные правила
],Одно правило создаёт весь набор адресов. Имя контроллера в адресе ставится во множественном числе: api/posts.
| Запрос | Что делает |
|---|---|
GET /api/posts | Список статей |
GET /api/posts/5 | Одна статья |
POST /api/posts | Создание |
PUT /api/posts/5 | Изменение |
DELETE /api/posts/5 | Удаление |
Проверка
curl http://localhost:8080/api/postsКоманда выведет массив статей в формате JSON. Список выдаётся страницами по 20 записей; общее число записей приходит в заголовке ответа X-Pagination-Total-Count, следующая страница — /api/posts?page=2.
Приём JSON
Чтобы API принимал данные в формате JSON, включите разборщик в компоненте request:
// config/web.php
'request' => [
'cookieValidationKey' => '...',
'parsers' => [
'application/json' => 'yii\web\JsonParser',
],
],Теперь статью можно создать запросом:
curl -X POST http://localhost:8080/api/posts \
-H "Content-Type: application/json" \
-d '{"title": "Из API", "body": "Текст статьи"}'Ответ — созданная статья и код 201. Если данные не проходят правила модели, вернётся код 422 и список ошибок по полям.
Выбор полей
По умолчанию в ответ попадают все столбцы таблицы. Список полей задаёт метод fields() модели:
// models/Post.php
public function fields(): array
{
return [
'id',
'title',
'body',
'published' => fn () => (bool) $this->status,
];
}В ответе останутся четыре поля, причём published вычисляется функцией. Этот метод особенно важен для модели User: без него API отдаст password_hash.
Доступ по ключу
Сейчас создать и удалить статью может кто угодно. Доступ закрывают фильтром аутентификации:
// controllers/api/PostController.php
use yii\filters\auth\HttpBearerAuth;
public function behaviors(): array
{
$behaviors = parent::behaviors();
$behaviors['authenticator'] = ['class' => HttpBearerAuth::class];
return $behaviors;
}Фильтр берёт ключ из заголовка Authorization: Bearer ... и передаёт его в метод User::findIdentityByAccessToken(). Этот метод должен найти пользователя по ключу — например, по отдельному столбцу access_token. Запрос без верного ключа получит код 401.
Частая ошибка
Если открыть /api/posts в браузере, придёт XML, а не JSON. Это не поломка: Yii выбирает формат по заголовку Accept, а браузер просит XML. Программы, которые отправляют Accept: application/json, как и curl, получают JSON.