aaronjan / kobe
Kobe是一个PHP的Swagger定义编写工具,它可以与Laravel等框架一起使用,也可以单独使用原生PHP。
Requires
- symfony/finder: 2.7.* || ~3.2
Suggests
- zircote/swagger-php: Kobe only knows the definitions of Swagger.
README
Kobe
是一个用于PHP
的Swagger定义编写工具,它可以与Laravel等框架一起使用,也可以单独使用原生PHP
。
Kobe只能生成Swagger规范中的定义部分,因此你必须与像zircote/swagger-php这样的功能齐全的库一起使用(或者你可以直接在PHP中使用数组来编写)。
为什么叫“Kobe”?嗯,我做了一些研究,根据互联网,Kobe Bryant最具Swagger风格,所以我想Kobe应该知道Swagger的定义。
注意
如果你使用的是swagger-php
版本2.0.11
,并且遇到了模式未找到的错误,请参阅这里。
简介
你肯定知道zircote/swagger-php。如果你以前使用过,你可能会像我一样抱怨以下这些事情
- 我该如何命名空间我的定义?
- 为什么编写嵌套内容这么痛苦?!为什么我必须写这么多定义仅仅为了嵌套?!
- 编写示例值让我感到要命...
不要放弃Swagger
,Kobe
就是为了定义
而存在的。
但是首先,我们必须了解Swagger
是如何工作的。
Swagger
是一个规范,它可以用多种方式表达,例如YAML
或JSON
,通常我们在PHP
中使用JSON
。所以无论你是否使用zircote/swagger-php
,最终的结果都只是一个JSON
字符串。
因此,你可以使用zircote/swagger-php
编写其他Swagger内容(因为它对其他内容都很好,只是定义
除外),并使用Kobe来组织你的定义
,
注意
Kobe目前没有任何测试,尽管我没有发现任何错误,但请小心。我会在有时间的时候编写一些测试,或者你可以帮助这个!
安装
通过Composer安装
$ composer require aaronjan/kobe
示例
让我们用一个简单的Laravel项目来演示Kobe
。
首先,我们创建一个文件夹app/Swagger/Definitions/
来存储所有的定义
,并在app/Swagger/BaseDefinition.php
中创建一个BaseDefinition
,如下所示
<?php namespace App\Swagger; use Kobe\Schemas\Definition; /** * Class BaseDefinition * * @package App\Swagger */ abstract class BaseDefinition extends Definition { /** * @return string */ public function getBaseNamespace() { return 'App\\Swagger\\Definitions\\'; } }
Kobe
默认使用类名生成Definition
名称(您也可以更改此行为),例如您的app\Swagger\Definitions\User\StoreResponse
的名称将是app.Swagger.Definitions.User.StoreResponse
。显然,编写ref="#/definitions/app.Swagger.Definitions.User.StoreResponse"
太罗嗦了,所以您可以在getBaseNamespace()
方法中返回一个前缀来简化您的类。
我们所有的Definition
都将扩展自这个BaseDefinition
。
好的,这是我们的第一个真正的Definition
app/Swagger/Definitions/Responses/ApiResponse.php
<?php namespace App\Swagger\Definitions\Responses; use App\Swagger\BaseDefinition; use Kobe\Kobe; /** * Class ApiResponse * * @package App\Swagger\Definitions\Responses */ class ApiResponse extends BaseDefinition { /** * DemoResponse constructor. */ public function __construct() { $this->setProperties([ 'code' => Kobe::makeInteger(), 'message' => Kobe::makeString(), 'type' => Kobe::makeString(), ]); } }
这最终将被转换为这样的JSON
(记住只有definitions
部分?)
{ "definitions": { "Responses.ApiResponse": { "type": "object", "properties": { "code": { "type": "integer", "format": "int32" }, "message": { "type": "string" }, "type": { "type": "string" }, } } } }
您可以编写尽可能多的Definition
,您也可以使用Kobe
,因为它只是PHP
!
例如,一个扩展自ApiResponse
的响应
app/Swagger/Definitions/Responses/FailureResponse.php
<?php namespace App\Swagger\Definitions\Responses; use Kobe\Kobe; /** * Class FailureResponse * * @package App\Swagger\Definitions\Responses */ class FailureResponse extends ApiResponse { /** * FailureResponse constructor. */ public function __construct() { parent::__construct(); $this->setProperties([ 'code' => Kobe::makeInteger()->setExample(400), 'message' => Kobe::makeString()->setExample('an error message'), 'type' => Kobe::makeString()->setExample('error'), ]); } }
您可以看到,为属性编写示例是如此简单。
最后,我们必须返回Swagger JSON
// Here is your controller method that returns the JSON public function getJSON() { // zircote/swagger-php $swagger = \Swagger\scan([ app_path('Http/Controllers/'), ]); // Scan the whole directory for any PHP file and parse the class instances to Swagger definitions $definitions = \Kobe\Kobe::scanPSR4( app_path('Swagger/Definitions/'), 'App\\Swagger\\Definitions\\' ); // Merge them together! $swaggerDefinition = array_merge( ((array) $swagger->jsonSerialize()), ['definitions' => $definitions] ); return response()->json($swaggerDefinition, 200); }
但在现实世界中事情往往更复杂,让我们写一些更多的例子。
app/Swagger/Definitions/User.php
<?php namespace App\Swagger\Definitions; use App\Swagger\BaseDefinition; use Kobe\Kobe; /** * Class User * * @package App\Swagger\Definitions */ class User extends BaseDefinition { /** * User constructor. */ public function __construct() { $this->setProperties([ 'id' => Kobe::makeInteger(), 'name' => Kobe::makeString(), ]); } }
app/Swagger/Definitions/Article.php
<?php namespace App\Swagger\Definitions; use App\Swagger\BaseDefinition; use Kobe\Kobe; /** * Class Article * * @package App\Swagger\Definitions */ class Article extends BaseDefinition { /** * Article constructor. */ public function __construct() { $this->setProperties([ 'id' => Kobe::makeInteger(), // $ref 'author_user_id' => Kobe::referenceByClass(User::class), 'title' => Kobe::makeString(), 'content' => Kobe::makeString(), ]); } }
app/Swagger/Definitions/ComplexStuff.php
<?php namespace App\Swagger\Definitions; use App\Swagger\BaseDefinition; use Kobe\Kobe; /** * Class ComplexStuff * * @package App\Swagger\Definitions */ class ComplexStuff extends BaseDefinition { /** * ComplexStuff constructor. */ public function __construct() { $configDefinition = Kobe::makeTempDefinition() ->setProperties([ 'boot' => Kobe::makeString() ->setDescription('boot mode: immediate, delay') ->setExample('delay'), 'retry' => Kobe::makeInteger(), ]); $extendedUserDefinition = Kobe::makeTempDefinitionFrom(User::class) ->setName('temp.ExtendedUser') ->setProperties([ 'permissions' => Kobe::makeString()->setExample('CREATE,UPDATE'), ]); $this->setProperties([ 'config' => $configDefinition->getReference(), 'extendedUser' => $extendedUserDefinition->getReference(), 'article' => Kobe::referenceByClass(Article::class), ]); } }
这是结果
{ // ... "definitions": { "ApiResponse": { "type": "object", "properties": { "code": { "type": "integer", "format": "int32" }, "message": { "type": "string" }, "type": { "type": "string" } } }, "Article": { "type": "object", "properties": { "id": { "type": "integer", "format": "int32" }, "author_user_id": { "$ref": "#\/definitions\/User" }, "title": { "type": "string" }, "content": { "type": "string" } } }, "ComplexStuff": { "type": "object", "properties": { "config": { "$ref": "#\/definitions\/temp.0c67cd34540a99c2" }, "extendedUser": { "$ref": "#\/definitions\/temp.ExtendedUser" }, "article": { "$ref": "#\/definitions\/Article" } } }, "User": { "type": "object", "properties": { "id": { "type": "integer", "format": "int32" }, "name": { "type": "string" } } }, "temp.0c67cd34540a99c2": { "type": "object", "properties": { "boot": { "description": "boot mode: immediate, delay", "type": "string", "example": "delay" }, "retry": { "type": "integer", "format": "int32" } } }, "temp.ExtendedUser": { "type": "object", "properties": { "id": { "type": "integer", "format": "int32" }, "name": { "type": "string" }, "permissions": { "type": "string", "example": "CREATE,UPDATE" } } } }, // ... }
Temp Definition
将自动获取一个随机名称(或者您可以手动设置),并将与您的其他所有Definition
一起解析。
API
Kobe\Kobe
scanPSR4($directory, $namespace, $depth = 3)
parseDefinitions(array $definitionClasses, $mergeWithTemp = true)
makeInteger()
makeSchema()
makeItems()
makeLong()
makeFloat()
makeDouble()
makeString()
makeByte()
makeBinary()
makeBoolean()
makeDate()
makeDateTime()
makePassword()
makeObject()
makeArray()
makeTempDefinition($save = true)
makeTempDefinitionFrom($class, $save = true)
referenceByClass($class)
referenceByName($name)
Kobe\Schemas\Definition
getName()
getReference()
setAllOf($parents)
getAllOf()
toArray()
setExample($example)
getExample()
setTitle($title)
getTitle()
setDefault($default)
getDefault()
setDescription($description)
getDescription()
setProperty($name, Understandable $value)
setProperties($properties)
getProperties()
addRequired($required)
setRequired(array $required)
getRequired()
setAdditionalProperties($additionalProperties)
getAdditionalProperties()
setItems(\Kobe\Schemas\Items $items)
setReferenceAsItems(\Kobe\Schemas\Reference $reference)
getItems()
asInteger()
asSchema()
asItems()
asLong()
asFloat()
asDouble()
asString()
asByte()
asBinary()
asBoolean()
asDate()
asDateTime()
asPassword()
asObject()
asArray()
getType()
setType($type)
getFormat()
setFormat($format)
Kobe\Schemas\TempDefinition
继承自 Kobe\Schemas\Definition
.
setName($name)
originToArray()
Lisence
遵循 Apache License 2.0 许可。