kevupton/laravel-swagger

Laravel 模型 Swagger 生成器

安装量: 13,904

依赖者: 1

建议者: 0

安全: 0

星标: 18

关注者: 1

分支: 4

开放问题: 1

类型:扩展

v1.4.2 2017-10-11 05:21 UTC

This package is auto-updated.

Last update: 2024-09-15 12:52:08 UTC


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 允许您为每个控制器定义一个通用的、定制的输出。它需要一个父控制器来定义每个输出响应的基础。

入门

例如,您有控制器 TestControllerFooControllerBarController,它们处理 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']);

我有一个自定义包来帮助处理控制器功能,您可以在 EtherealResource 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;
	}
}

重写值

如果您的 子控制器 包含静态变量的定义,并覆盖父控制器的值,则 子控制器 的值将生效。

分离容器类

您不必在您的 控制器中直接定义 getSwaggerMethodsgetSwaggerRoutesgetSwaggerHandler,您可以在一个单独的类中定义它们。

然后,您可以使用静态变量 $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;
}