Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

REST API

API — набор адресов, которые отдают не страницы HTML, а данные в формате JSON. К ним обращаются мобильные приложения и программы на JavaScript. В подходе REST каждый адрес обозначает ресурс, например статьи, а метод HTTP — действие над ним. Контроллеры API удобно держать в отдельной папке app/Controllers/Api.

Контроллер

Создайте вручную файл app/Controllers/Api/Posts.php:

// app/Controllers/Api/Posts.php
namespace App\Controllers\Api;
 
use App\Models\PostModel;
use CodeIgniter\RESTful\ResourceController;
 
class Posts extends ResourceController
{
    protected $modelName = PostModel::class;
    protected $format = 'json';
 
    public function index()
    {
        return $this->respond($this->model->findAll());
    }
}

Класс ResourceController — контроллер для API. Модель из $modelName доступна как $this->model, а метод respond() превращает массив в ответ JSON.

Маршруты

// app/Config/Routes.php
$routes->resource('api/posts', ['controller' => 'Api\Posts']);

Откройте /api/posts — браузер покажет список статей в формате JSON. Одна строка resource() создаёт целый набор маршрутов:

ЗапросМетод контроллера
GET /api/postsindex()
GET /api/posts/5show(5)
POST /api/postscreate()
PUT /api/posts/5update(5)
DELETE /api/posts/5delete(5)

Одна запись

public function show($id = null)
{
    $post = $this->model->find($id);
 
    if ($post === null) {
        return $this->failNotFound('Статья не найдена');
    }
 
    return $this->respond($post);
}

Адрес /api/posts/1 вернёт одну статью, а /api/posts/999 — код 404 и сообщение об ошибке в формате JSON.

Создание

public function create()
{
    $rules = [
        'title' => 'required|min_length[5]',
        'body' => 'required',
    ];
 
    $data = $this->request->getJSON(true) ?? [];
 
    if (! $this->validateData($data, $rules)) {
        return $this->failValidationErrors($this->validator->getErrors());
    }
 
    $id = $this->model->insert($this->validator->getValidated());
 
    return $this->respondCreated($this->model->find($id));
}

getJSON(true) читает тело запроса как массив. При ошибке клиент получает список сообщений по полям, при успехе — код 201 и созданную запись. Проверить такой запрос можно программой для тестирования API или командой curl.

Методы ответа

МетодКод
respond($data)200
respondCreated($data)201
respondDeleted($data)200
respondNoContent()204
failValidationErrors($errors)400
failUnauthorized()401
failForbidden()403
failNotFound()404

ResponseTrait

Те же методы можно получить в обычном контроллере, подключив трейт — набор методов, добавляемый в класс:

// app/Controllers/Posts.php
use CodeIgniter\API\ResponseTrait;
 
class Posts extends BaseController
{
    use ResponseTrait;
 
    public function count()
    {
        return $this->respond(['total' => model(PostModel::class)->countAllResults()]);
    }
}

Защита

Если включён глобальный фильтр csrf, запросы POST к API без токена будут отклонены. Для адресов API его отключают в app/Config/Filters.php: 'csrf' => ['except' => ['api/*']], а сами маршруты закрывают фильтром, проверяющим токен доступа, — например фильтром tokens из пакета Shield.

Частая ошибка

respond() отправит всё, что вернула модель, включая служебные столбцы. Для таблицы пользователей это означает, что клиент получит хеши паролей. Перечисляйте нужные столбцы явно: $this->model->select('id, title, created_at')->findAll().

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.