tochka-developers / openrpc
OpenRpc extension for tochka-developers/jsonrpc
Requires
- php: >=8.0
- ext-json: *
- illuminate/console: ^8.0|^9.0|^10.0
- illuminate/container: ^8.0|^9.0|^10.0
- illuminate/pipeline: ^8.0|^9.0|^10.0
- illuminate/support: ^8.0|^9.0|^10.0
- spiral/attributes: ^2.8
- tochka-developers/jsonrpc: ^4.0|^5.0
- tochka-developers/jsonrpc-annotations: ^1.1
Requires (Dev)
- mockery/mockery: ^1.0
- phpunit/phpunit: ^10.0
- roave/security-advisories: dev-latest
README
Описание
Пакет для автоматической генерации документации JsonRpc-сервера по стандарту OpenRpc (https://spec.open-rpc.org/).
Совместим с пакетом tochka-developers/jsonrpc
>=v4.0
Установка
Установка через composer:
composer require tochka-developers/openrpc
Laravel
Для Laravel есть возможность опубликовать конфигурацию для всех пакетов:
php artisan vendor:publish
Для того, чтобы опубликовать только конфигурацию данного пакета, можно воспользоваться опцией tag
php artisan vendor:publish --tag="openrpc-config"
Lumen
В Lumen отсутствует команда vendor:publish, поэтому делается это вручную. Если в проекте еще нет директории для конфигураций - создайте ее:
mkdir config
Скопируйте в нее конфигурацию openrpc:
cp vendor/tochka-developers/openrpc/config/openrpc.php config/openrpc.php
Вместо config/openrpc.php нужно указать любую другую директорию, где хранятся ваши конфиги и название будущего конфига. Далее необходимо прописать скопированный конфиг в bootstrap/app.php
$app->configure('openrpc');
Так же прописать провайдер:
$app->register(\Tochka\OpenRpc\OpenRpcServiceProvider::class);
Где jsonrpc - имя файла конфига
Для корректной работы так же необходимы фасады:
$app->withFacades();
Настройка точки входа
Укажите в конфигурации openrpc.endpoint
точку входа для получения схемы OpenRpc:
'endpoint' => '/api/openrpc.json'
В дальнейшем эта точка входа будет использована для Service Discovery Method.
Кеширование
OpenRpc может кешировать схему с описанием JsonRpc, чтобы не собирать ее каждый раз при вызове endpoint. Для создания кеша используйте команду artisan:
php artisan openrpc:cache
После выполнения этой команды будет выполнена сборка схемы и сохранена в файл кеша. При каждом следующем обращении к OpenRpc будет использован именно этот файл, повторной пересборки происходить не будет.
Если файла с кешем нет - схема каждый раз будет собираться заново.
Чтобы очистить кеш - используйте команду artisan:
php artisan openrpc:clear
Рекомендуется запускать команду кеширования сразу после деплоя перед запуском приложения.
Как использовать
Аннотации и атрибуты
Некоторые пометки или уточнения для классов, методов и полей могут использовать аннотации (https://www.doctrine-project.org/projects/doctrine-annotations/en/1.10/index.html) или атрибуты (https://www.php.net/manual/ru/language.attributes.overview.php). Все классы аннотаций/атрибутов обратно совместимы и могут работать и как аннотации (для версии PHP<8), и как атрибуты (для версии PHP>=8). Примеры использования аннотаций:
use Tochka\JsonRpc\Annotations\ApiIgnore; use Tochka\JsonRpc\Annotations\ApiValueExample; use Tochka\JsonRpc\Annotations\ApiArrayShape; /** * @ApiIgnore() */ class TestDTO { /** * @ApiValueExample(examples={1, 5, 6}) */ public ?int $int; /** * @ApiArrayShape(shape={"test": "string", "foo": "int", "bar": "array", "object": FooObject::class}) */ public array $testShape; }
Пример использования атрибутов:
use Tochka\JsonRpc\Annotations\ApiIgnore; use Tochka\JsonRpc\Annotations\ApiValueExample; use Tochka\JsonRpc\Annotations\ApiArrayShape; #[ApiIgnore] class TestDTO { #[ApiValueExample(examples: [1, 5, 6])] public ?int $int; #[ApiArrayShape(shape: ['test' => 'string', 'foo' => 'int', 'bar' => 'array', 'object' => FooObject::class])] public array $testShape; }
Расширенное описание
Во многих объектах спецификации OpenRpc есть поле description, которое позволяет использовать MarkDown разметку. Для более удобной организации есть возможность выносить эти описания в отдельные файлы с расширением .md, и затем в описании ссылаться на них:
'description' => '$views/docs/description.md'
В данном случае вместо указанного текста в поле подставится содержимое файла resources/views/docs/description.md
.
Будьте внимательны! Документы должны находиться в папке resources, так как путь к файлу строится относительно этой
директории.
Основная информация
Вся основная информация о вашем приложении заполняется в конфигурации openrpc.php
. В дефолтной конфигурации
описаны все поля, а также приведены примеры
Информация о серверах (ендпойнты)
Ваше приложение может иметь несколько точек входа с разным списком методов. Все возможные конфигурации точек входа
JsonRpc-сервера описываются в конфигурации jsonrpc.php
. Для корректного вывода информации о точках входа в OpenRpc
необходимо добавить еще несколько полей в конфигурацию каждого сервера JsonRpc:
/** Адрес endpoint для текущего сервера */ 'endpoint' => '/api/v1/public/jsonrpc', /** Базовая информация о сервере/точки входа */ 'summary' => 'Основная точка входа', /** Расширенное описание сервера/точки входа */ 'description' => 'Основная точка входа',
Информация о методах
OpenRpc собирает информацию о доступных методах, получая информацию о маршрутах из JsonRpc-сервера.
Информация о формате запроса
Если в методе используется аннотация/атрибут
ApiMapRequestToObject
, то в качестве параметров метода будут указаны поля класса, в который JsonRpc будет маппить запрос.
Если используется стандартное прокидывание параметров запроса в параметры метода - то OpenRpc будет собирать информацию
об используемых параметрах из этих параметров метода. При этом учитывается типизация, а также дополнительной описание
параметров с помощью PhpDoc (тег @param
).
Вы можете уточнять тип вложенных в массив элементов также с помощью тегов @param
и @return
:
/** * @param array<MyType> $foo Описание параметра FOO * @param string[] $bar Описание параметра BAR * @return Result[] */ public function myMethod(array $foo, array $bar): array { // ... }
Если в качестве типа указан какой-либо класс - OpenRpc попытается описать внутреннюю структуру класса.
По умолчанию выбираются все публичные поля класса. Кроме того, учитываются поля, описанные в phpDoc
(помеченные атрибутом @property
).
В качестве типа аргумента всегда выбирается тип поля. Поле считается обязательным, если у него нет дефолтного значения.
Если в качестве типа поля указан array
- вы можете уточнить тип элементов массива с помощью phpDoc в атрибуте @var
:
class TestDTO { /** @var array<int> */ public array $field; /** @var MyObject[] */ public array $objects; }
Если в качестве типа указан экземпляр BenSampo\Enum\Enum
- OpenRpc автоматически получит все варианты значений для поля,
и попытается вычислить тип. Информация о возможных значениях будет отражена в схеме.
Если в качестве типа указан экземпляр Illuminate\Database\Eloquent\Model
- OpenRpc получит все возможные поля из phpDoc
(как указано выше), а затем попытается отфильтровать их в соответствии с правилами, указанными в hidden и visible
(https://laravel.com/docs/8.x/eloquent-serialization#hiding-attributes-from-json)
Для указания примеров значений для аргумента используйте аннотацию/атрибут ApiValueExample
:
use Tochka\JsonRpc\Annotations\ApiValueExample; class TestDTO { #[ApiValueExample(examples: [1, 3, 5])] public int $field; /** * @ApiValueExample(examples={"foo", "bar"}} */ public string $foo; }
Для указания вариантов возможных значений (если не используется Enum) - используйте аннотацию/атрибут ApiExpectedValues
:
use Tochka\JsonRpc\Annotations\ApiExpectedValues; class TestDTO { #[ApiExpectedValues(values: [1, 3, 5])] public int $field; /** * @ApiExpectedValues(values={"foo", "bar"}} */ public string $foo; }
Для указания формата объекта (если для него нет отдельного класса) - используйте аннотацию/атрибут ApiArrayShape
:
use Tochka\JsonRpc\Annotations\ApiArrayShape; class TestDTO { #[ApiArrayShape(shape: ['test' => 'string', 'foo' => 'int', 'bar' => 'array', 'object' => FooObject::class])] public int $field; /** * @ApiArrayShape(shape={"test": "string", "foo": "int", "bar": "array", "object": FooObject::class}} */ public string $foo; }
Первая строка описания поля в phpDoc считается summary - и отображается в кратком описании аргумента в схеме. Вторая и следующие строки описания поля в phpDoc считаются description - и отображаются в полном описании аргумента в схеме. При этом разрешено ссылаться на MarkDown файл:
class TestDTO { /** * Это будет summary * А вот это будет description */ public int $someField; /** * Это будет summary * $views/docs/description.md // содержимое этого файла будет description */ public string $foo; }
Информация об ответе
OpenRpc забирает информацию о формате ответа из типа, указанного в качестве результата метода. При этом тип может быть указан также в phpDoc этого метода. При этом все возможности OpenRpc, описанные в предыдущем пункте для запросов - будут также работать и для описания формата ответа.
Кроме того, дополнительно есть возможность описать формат ответа с помощью атрибута/аннотации ApiArrayShape
:
use Tochka\JsonRpc\Annotations\ApiArrayShape; class TestController { #[ApiArrayShape(shape: ['test' => 'string', 'foo' => 'int', 'bar' => 'array', 'object' => FooObject::class])] public function someMethod(): array { return []; } /** * @ApiArrayShape(shape={"test": "string", "foo": "int", "bar": "array", "object": FooObject::class}} */ public function fooMethod(): array { return []; } }
Также аннотацию/атрибут ApiArrayShape
можно использовать для описания структуры класса:
use Tochka\JsonRpc\Annotations\ApiArrayShape; /** * @ApiArrayShape(shape={"test": "string", "foo": "int", "bar": "array", "object": FooObject::class}) */ class MyResultClass { //... }
Также эту аннотацию можно использовать для переопределения структуры какого либо свойства класса:
use Tochka\JsonRpc\Annotations\ApiArrayShape; class MyResultClass { #[ApiArrayShape(shape: ['test' => 'string', 'foo' => 'int', 'bar' => 'array', 'object' => FooObject::class])] public SomeClass $property; }
Примеры запросов и ответов
В разработке...
Ошибки
В разработке...