kevupton / laravel-swagger
Laravel 模型 Swagger 生成器
Requires
- php: >=5.3
- doctrine/dbal: ~2.3
- zircote/swagger-php: ^2.0
Requires (Dev)
- laravel/laravel: ^5.5
- laravel/lumen: ^5.5
README
Laravel 5.0 及以上版本使用的 Swagger 注释生成器。
简介
此包使用 Swagger PHP 库和 Laravel 生成符合 OpenAPI 3.0 规范的 JSON 规范。
此包支持 Laravel 5.0 及以上版本。
安装
$ composer require kevupton/laravel-swagger
目录
模型
用法
\Kevupton\LaravelSwagger\scan($path, $models);
按照以下示例定义您的 Eloquent 模型,以便 laravel-swagger
能够将其包含在规范中
/** @var Swagger\Annotations\Swagger $swagger */ $swagger = \Kevupton\LaravelSwagger\scan(app_path('location'), [ 'models' => [ /** All models go in here */ \App\Models\User::class, ] ]);
示例模型
class User { protected $table = 'users'; protected $fillable = ['first_name', 'last_name', 'image_id']; protected $hidden = ['created_at', 'updated_at', 'image_id']; protected $with = ['image']; public $timestamps = true; public function image() { return $this->belongsTo(Image::class); } }
输出
"App\\Models\\User": { "properties": { "id": { "type": "string" }, "first_name": { "type": "string" }, "last_name": { "type": "string" }, "image": { "$ref": "#/definitions/App\\Models\\Image" } } }
控制器
Laravel-Swagger 允许您为每个控制器定义一个通用的、定制的输出。它需要一个父控制器来定义每个输出响应的基础。
入门
例如,您有控制器 TestController
、FooController
和 BarController
,它们处理 API 请求。
每个 index
方法具有相似的功能,即显示具有分页的结果列表。路由定义如下
示例路由定义
Route::get('/v1/test', ['uses' => 'TestController@index', 'as' => 'v1.test.index']); Route::get('/v1/foo', ['uses' => 'FooController@index', 'as' => 'v1.foo.index']); Route::get('/v1/bar', ['uses' => 'BarController@index', 'as' => 'v1.bar.index']); Route::get('/v1/bar/{bar}', ['uses' => 'BarController@show', 'as' => 'v1.bar.show']);
我有一个自定义包来帮助处理控制器功能,您可以在 Ethereal 的 Resource Trait 找到它。
由于这些控制器具有相同的基本输出,您可以使用上述控制器可以继承的 BaseController
。以下是一个 BaseController
的示例
示例基控制器
<?php namespace App\Http\Controllers; use Illuminate\Routing\Controller; use Kevupton\LaravelSwagger\DynamicMethod; use Swagger\Annotations\Parameter; use Swagger\Annotations\Response; class BaseController extends Controller { //Define the function that returns the dynamic methods public static function getSwaggerRoutes() { return [ 'index' => DynamicMethod::GET([ 'tags' => ['{{tag}}'], 'summary' => '{{summary}}', 'parameters' => [ new Parameter([ 'in' => 'query', 'name' => 'page', 'description' => 'the page number', 'required' => false, 'type' => 'string' ]) ], 'value' => new Response([ 'response' => 200, 'description' => 'test', 'ref' => '{{response}}' ]) ]) ]; } }
getSwaggerRoutes
是一个方法,用于定义上述控制器的规范模板结构。
您会注意到,在上面的定义中包含了一些占位符值,例如 {{response}}
。这些值将替换为每个子控制器中找到的值。请参阅 keys 部分的相关内容。
路由匹配
如 此处 所示的 routing 定义,键 index
指的是上述 Router 定义中路由键 index
。
例如,如 上述,在 getSwaggerRoutes
中定义的路由键 index
将应用于路由 v1.bar.index
,而不是 v1.bar.show
。
同样,v1.test.index
将匹配上述定义,但不会匹配 v1.index.test
。
键
{{keyname}} keyname 指的是您的控制器中静态变量的名称,其值将被替换。
public static $keyname = 'Value that will be replaced';
如 示例 所示,您可以看到示例键
'tags' => ['{{tag}}'], 'summary' => '{{summary}}', 'value' => '{{response}}',
默认处理程序将在 子控制器 中搜索与每个变量同名的内容,并将键替换为变量包含的值。
示例子控制器
class TestController { public static $tag = "my custom tag"; public static $summary = "how awesome is this"; public static $response = "#/definitions/Response"
示例输出
这是 swagger json 输出中位于路径的一部分。
{ "/v1/test": { "get": { "tags": [ "my custom tag" ], "summary": "how awesome is this", "parameters": [ { "name": "page", "in": "query", "description": "the page number", "required": false, "type": "string" }, ], "responses": { "200": { "description": "test", "schema": { "$ref": "#/definitions/dynamic-definition-1" } } } }, }
注意 默认处理程序将使用与控制器中同名的 静态 变量替换键。您可以在 修改默认行为 部分中修改此行为。
自定义处理程序
定义
如果您需要更改默认处理器的默认行为,您可以扩展处理器类,并实现下面的 handle
方法。
<?php namespace App\Handlers; use Kevupton\LaravelSwagger\DynamicHandler; use Kevupton\LaravelSwagger\LaravelSwagger; use Kevupton\LaravelSwagger\ValueContainer; class CustomHandler extends DynamicHandler { /** * The handler which sets all the values in the dynamic definition. * * @param String $class the Controller class name * @param LaravelSwagger $LS the LaravelSwagger instance. * @throws DynamicHandlerException */ public function handle($class, LaravelSwagger $LS) { //all the registered keys $keys = $this->method->keys(); $key = 'response'; //get the value of from the class $value = ValueContainer::getValue($class, $key); /** * Do some handling here of the value? */ //to set a registered key $this->method->set($key, $value); } }
要使用您的新自定义处理器,您可以在下面定义 getSwaggerHandler
,返回新自定义处理器的 ::class
,如下所示。
自定义处理器实现示例
use App\Handlers\CustomHandler; class BaseController extends Controller { //The method for defining the custom handler public static function getSwaggerHandler() { return CustomHandler::class; } }
重写值
如果您的 子控制器 包含静态变量的定义,并覆盖父控制器的值,则 子控制器 的值将生效。
分离容器类
您不必在您的 父 和 子 控制器中直接定义 getSwaggerMethods
、getSwaggerRoutes
和 getSwaggerHandler
,您可以在一个单独的类中定义它们。
然后,您可以使用静态变量 $swagger_container
将其包含在您的 BaseController 或任何其他控制器中。请参考下面的示例。
自定义容器实现示例
<?php namespace App\Swagger; use Kevupton\LaravelSwagger\DynamicMethod; use Kevupton\LaravelSwagger\MethodContainer; class CustomContainer extends MethodContainer { /** * Gets * @return DynamicMethod[] */ public function getSwaggerMethods() { // TODO: Implement getSwaggerMethods() method. } /** * Gets the Routes for the container * * @return DynamicMethod[] */ public function getSwaggerRoutes() { // TODO: Implement getSwaggerRoutes() method. } /** * Gets the default Handler class * * @return string the Class Name of the DynamicHandler instance */ public function getSwaggerHandler() { // TODO: Implement getSwaggerHandler() method. } }
基础控制器实现示例
use App\Swagger\CustomContainer; class BaseController extends Controller { public static $swagger_container = CustomContainer::class; }