tochka-developers / openrpc
为tochka-developers/jsonrpc提供的OpenRpc扩展
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
描述
用于根据OpenRpc标准自动生成JsonRpc服务器文档的包(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://php.ac.cn/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 将尝试描述类的内部结构。
默认情况下,选择所有公共字段。此外,还考虑了带有 @property
属性标记的 phpDoc 中描述的字段。
始终选择字段类型作为参数类型。如果没有默认值,则认为字段是必需的。
如果指定了 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.net.cn/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 - 并在方案中显示为参数的简短描述。第二行和随后的行被认为是 description - 并在方案中显示为参数的完整描述。在此过程中,允许引用 MarkDown 文件。
class TestDTO { /** * Это будет summary * А вот это будет description */ public int $someField; /** * Это будет summary * $views/docs/description.md // содержимое этого файла будет description */ public string $foo; }
响应信息
OpenRpc 从方法结果中指定的类型中获取响应格式信息。在这种情况下,类型也可以在方法的 phpDoc 中指定。在这种情况下,OpenRpc 在请求中描述的所有 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; }
请求和响应示例
开发中...
错误
开发中...