archee-nic / decl-api
Декларативный API
Requires
- php: ^7.3
- ext-json: *
- illuminate/filesystem: >=5.4
- illuminate/translation: >=5.4
- illuminate/validation: >=5.4
- league/flysystem: ^1.0
Requires (Dev)
- phpunit/phpunit: >=6.0
- roave/security-advisories: dev-master
This package is not auto-updated.
Last update: 2023-05-09 20:23:15 UTC
README
Оглавление
- О библиотке
- Создаём поинт
- Примеры использования
О библиотке
Установка
В composer проекта добавить строки
"repositories": [
{
"type": "vcs",
"url": "gogs@gogs.inetpartners.org:archee-nic/decl-api.git"
}
]
Далее в консоли можно написать
composer require archee-nic/decl-api
Описание
DeclApi - библиотека декларативного API
Это значит, что разработчик сначала описывает правила, по которым получается информация и отдается, а потом уже пишется сама логика
Библиотека реализована с максимальной изоляцией от любых фреймворков.
За счет того, что реализуется декларативная логика, есть возможность сгенерировать документацию и провести автоматический тест на работоспособность API.
За счет изоляции от фреймворков - переезд будет менее болезненен, а родительская архитектура будет той же
За счет того чтоб библиотека
Термины и определения
EndPoint - URI с собственной логикой.
Класс EndPoint - класс с логикой эндпоинта
Объект API - класс набора данных в рамках одного уровня
Класс Request - объект API с информацией о входящих данных
Приципы и архитектура
...
Создаём поинт
Создание класса Request
Отличие Request от обычного Объекта, то, что у него в качестве входящих данных идут массивы групп полей: json, parameter (get,post), header
В папке App/Api создадим файл для работы с входящими данными ExampleRequest
<?php namespace App\Api; use DeclApi\Core\Request; class ExampleRequest extends Request { } ?>
Добавим правило для get/post передавемого параметра
/** * @throws \Exception */ protected function initRules() { parent::initRules(); $this->rulesInfo()->add('parameter','integer','example','Пример поля','Пример описания поля')->setDefault(10)->setAttributes('required'); }
Создание класса Response
Класс response - обычныый объект - ObjectClass, для порядка все-таки рекомендуется называть его с окончанием Response, чтобы было понятно назначение объекта
В папке App/Api создадим файл для работы с входящими данными ExampleRequest
<?php namespace App\Api; use DeclApi\Core\ObjectClass; class ExampleResponse extends ObjectClass { }
Добавим правило для хранимого параметра
/** * @throws \Exception */ protected function initRules() { parent::initRules(); $this->rulesInfo()->add('integer','example','Пример параметра','Описание параметра'); }
Создание поинта
Будем рассматривать на примере laravel 5
В папке app/Http создадим подпапку Api В папке app/Http создадим подпапку Api
Название и расположение папки и файлов не имеет значения и ограничена только архитектурой и настройками фреймворка.
В Laravel 5 api.php использует в качестве основной папки для поиска целей роутов
app/Http
Внутри папки создадим класс Endpoint ExamplePoint.php со следующим содержимым:
<?php namespace App\Http\Api; use DeclApi\Core\PointL5Bridge; class ExamplePoint extends Laravel5Point { }
Обратите внимание на родительский класс PointL5Bridge - это мост для интеграции библиотеки в Laravel 5. Он является дочерним классом Point.
Если реализация будет требоваться в другом фреймворке - можно написать аналогичный мост и спользовать его. Так же можно использовать чистый Point
Теперь в созданный класс добавим метод
/** * @param ExampleRequest $request * * @return ExampleResponse * @throws \Exception */ public function handler(ExampleRequest $request): ExampleResponse { $data = new ExampleResponse(); return $data; }
Над классом добавим используемые неймспейсы
use App\Api\ExampleRequest;
use App\Api\ExampleResponse;
Интеграция с laravel 5.4+
Так как в качестве родителя мы использовали мост для laravel 5, нам не нужно писать какие либо особые правила или нстраивать связь для работы библиотеки
Добавим в api.php строку
Route::get('/example','Api\ExamplePoint');
Теперь наш Point будет вызываться при обращении по URI /api/example
Принцип работы
Кратко о структуре:
1. Endpoints
Для каждого endpoint создается класс с логикой вызываемой через handler.
- На входе класс, который содержит описание структуры входящих данных. (отличается от request, что там хранятся данные, а не магия вроде дерганья заголовков)
- На выходе класс, который содержит структуру возвращаемых данных и сами данные.
Профит кратко: Строгость, предсказуемость, актуальная дока, повторное использование, самотестирование,
Профит подробно:
- Строгость: Ты не можешь вернуть просто строку или массив. Метод всегда ждет на return instance класса DeclApiObject, который отввечает за хранение данных.
- Предсказуемость: В DeclApiObject поисываются правила и поля. (типа validator). Если они отличаются от ожидаемых (например - лишние поля) - будет exception. Это гарантирует что, например при использовании
Select *
влоб - пользователь не получит лишние неожиданные данные. - Актуальная дока: Генератор ориентируется на метод вызова, имя входящего класса и исходящего. И описанные (задекларированные) там поля и создает доку в формате OpenApi3 (технически заложена возможность расширить генератор до, например BluePrint формата). Поэтому пересоставлять доку всякий раз, когда ты меняешь api - не надо
- Повторное использование: Так как класс имеет одну самостоятельную логику с заранее согласованными данными на вход/выход, ее можно вызывать в консоли или вообще где хочется использовать.
- Самотестирование: По тому жо принципу что делается документирование, классы способны сгенерировать тестовые данные на вход и выход. А также попробовать исполнить код.
2. Мосты
Т.к. реализуемые классы Endpoints самодостаточны, они могут использоваться с "фишкой" роутингов laravel - когда для роута используется класс через __invoke Отсюда легкая интеграция с Laravel Аналогично и с разными доками. Общий стандарт позволяет генератору получить заранее готовые данные и кроить его уже на свой манер
3. Валидация
Для валидации поступающих полей используется illuminate/validation
Рекомендуемая структура файлов
Api
корневая папка Apiv1
- Подпапка раздела APIconfigs
- Подпапка файлов настроек