简介
api文档是个比较重要的话题,每个团队都有自己的api习惯,比如我们目前用的apizza来管理接口,也可以用postman。但是不管用什么感觉前端对后端的接口都不是很满意:)(手动狗头),这个问题不过多讨论,下面介绍一种比较强大的swagger
,集成到laravel中的一些用法。
swagger集成分为swagger-php 和 swagger-ui,可以分别安装,swagger-php用来编写文档的注解,生成json或其它格式的注解,swagger-ui是一个前端项目,负责将json导入到项目,以便直接访问调试。
文档地址(包括安装方法和版本对比)
github.com/DarkaOnLine/L5-Swagger/...
附录 swagger-php2和swagger-php3.0的比较文档 zircote.github.io/swagger-php/Migr...
无非就是移除了一些属性,修改了一些属性,将@SWG改为了@OA
根据本文章案例用的是laravel 8.0,所以需要用最新版的swagger3.0,安装方法如下:
1.安装
composer require "darkaonline/l5-swagger" | |
php artisan vendor:publish --provider "L5Swagger\L5SwaggerServiceProvider" | |
## 先把配置文件加上.env 最后加上L5_SWAGGER_CONST_HOST = http://homestead.test/ | |
打开config/l5-swagger.php 配置文件 | |
'constants' => ['L5_SWAGGER_CONST_HOST' => env('L5_SWAGGER_CONST_HOST', 'http://my-default-host.com'),], | |
php artisan l5-swagger:generate // 此命令是重置swagger的json,每次编写都要重新运行一下,如果想要自动生成也可以 |
2.app\Http\Controllers\Controller.php 下加上swagger注释
(这是官方文档的注释github.com/DarkaOnLine/L5-Swagger/...)
/** | |
* @OA\Info( | |
* version="1.0.0", | |
* title="L5 OpenApi", | |
* description="L5 Swagger OpenApi description", | |
* @OA\Contact( | |
* email="darius@matulionis.lt" | |
* ), | |
* @OA\License( | |
* name="Apache 2.0", | |
* url="http://www.apache.org/licenses/LICENSE-2.0.html" | |
* ) | |
* ) | |
*/ | |
/** | |
* @OA\Server( | |
* url=L5_SWAGGER_CONST_HOST, | |
* description="L5 Swagger OpenApi dynamic host server" | |
* ) | |
* | |
* @OA\Server( | |
* url="https://projects.dev/api/v1", | |
* description="L5 Swagger OpenApi Server" | |
* ) | |
*/ | |
/** | |
* @OA\SecurityScheme( | |
* type="oauth2", | |
* description="Use a global client_id / client_secret and your username / password combo to obtain a token", | |
* name="Password Based", | |
* in="header", | |
* scheme="https", | |
* securityScheme="Password Based", | |
* @OA\Flow( | |
* flow="password", | |
* authorizationUrl="/oauth/authorize", | |
* tokenUrl="/oauth/token", | |
* refreshUrl="/oauth/token/refresh", | |
* scopes={} | |
* ) | |
* ) | |
*/ | |
/** | |
* @OA\OpenApi( | |
* security={ | |
* { | |
* "oauth2": {"read:oauth2"}, | |
* } | |
* } | |
* ) | |
*/ | |
/** | |
* @OA\Tag( | |
* name="project", | |
* description="Everything about your Projects", | |
* @OA\ExternalDocumentation( | |
* description="Find out more", | |
* url="http://swagger.io" | |
* ) | |
* ) | |
* | |
* @OA\Tag( | |
* name="user", | |
* description="Operations about user", | |
* @OA\ExternalDocumentation( | |
* description="Find out more about", | |
* url="http://swagger.io" | |
* ) | |
* ) | |
* @OA\ExternalDocumentation( | |
* description="Find out more about Swagger", | |
* url="http://swagger.io" | |
* ) | |
*/ | |
/** | |
* @OA\Get( | |
* path="/projects", | |
* operationId="getProjectsList", | |
* tags={"Projects"}, | |
* summary="Get list of projects", | |
* description="Returns list of projects", | |
* @OA\Response( | |
* response=200, | |
* description="successful operation" | |
* ), | |
* @OA\Response(response=400, description="Bad request"), | |
* security={ | |
* {"api_key_security_example": {}} | |
* } | |
* ) | |
* | |
* Returns list of projects | |
*/ | |
/** | |
* @OA\Get( | |
* path="/projects/{id}", | |
* operationId="getProjectById", | |
* tags={"Projects"}, | |
* summary="Get project information", | |
* description="Returns project data", | |
* @OA\Parameter( | |
* name="id", | |
* description="Project id", | |
* required=true, | |
* in="path", | |
* @OA\Schema( | |
* type="integer" | |
* ) | |
* ), | |
* @OA\Response( | |
* response=200, | |
* description="successful operation" | |
* ), | |
* @OA\Response(response=400, description="Bad request"), | |
* @OA\Response(response=404, description="Resource Not Found"), | |
* security={ | |
* { | |
* "oauth2_security_example": {"write:projects", "read:projects"} | |
* } | |
* }, | |
* ) | |
*/ |
直接访问文档就可以了,例如:
homestead.test/api/documentation
附录:以下是我整理的文档结构:
定义公共的返回值并添加引用
注意:During processing the @OA\JsonContent unfolds to @OA\MediaType( mediaType=”application/json”, @OA\Schema( and will generate the same output.
这段话是文档上写的,大家可以试试,我这里就不试了
/** | |
* @OA\Get( | |
* path="/projects/{id}", | |
* operationId="getProjectById", | |
* tags={"Projects"}, | |
* summary="Get project information", | |
* description="Returns project data", | |
* @OA\Parameter( | |
* name="id", | |
* description="Project id", | |
* required=true, | |
* in="path", | |
* @OA\Schema( | |
* type="integer" | |
* ) | |
* ), | |
* @OA\Response( | |
* response=200, | |
* description="successful operation", | |
* @OA\MediaType( | |
* mediaType="application/json", | |
* @OA\Schema(ref="#/components/schemas/DoctorDuty"), | |
* ) | |
* ), | |
* @OA\Response(response=400, description="Bad request"), | |
* @OA\Response(response=404, description="Resource Not Found"), | |
* security={ | |
* { | |
* "oauth2_security_example": {"write:projects", "read:projects"} | |
* } | |
* }, | |
* ) | |
* | |
* | |
* @OA\Schema( | |
* schema="DoctorDuty", | |
* type="object", | |
* required={""}, | |
* example={ | |
"data": { | |
{ | |
"id": 1, | |
"week_name": "周一", | |
"created_at": null, | |
"updated_at": null, | |
"days": { | |
{ | |
"id": 1, | |
"work_period": "上午8~12点", | |
"parent_id": 1, | |
"type": 1, | |
"created_at": null, | |
"updated_at": null | |
}}}}}, | |
* @OA\Property(property="id",type="integer",example="1",description="自增id"), | |
* @OA\Property(property="week_name",type="integer",example="周一",description="药店id"), | |
* @OA\Property(property="days",type="array",example="",description="每周下面的具体排期", | |
* @OA\Items( | |
* @OA\Property(property="type",type="integer",example="1",description="1表示工作时间2表示下班时间3表示任何时间"), | |
* @OA\Property(property="work_period",type="integer",example="1",description="描述上下班时间"), | |
* @OA\Property(property="parent_id",type="integer",example="1",description="周id"), | |
* @OA\Property(property="created_at",type="string",example="2020-01-15 13:22:57",description="添加时间"), | |
* @OA\Property(property="updated_at",type="string",example="2020-01-15 13:22:57",description="更新时间"), | |
* )), | |
* @OA\Property(property="created_at",type="string",example="2020-01-15 13:22:57",description="添加时间"), | |
* @OA\Property(property="updated_at",type="string",example="2020-01-15 13:22:57",description="更新时间") | |
* ) | |
*/ |
上面列举了怎么采用引用的方法避免重复代码,如果不需要可以直接写在代码里面去掉ref
,
关于这部分的文档:
zircote.github.io/swagger-php/Gett...
下面是直接写:
/** | |
* @OA\Get( | |
* path="/projects", | |
* operationId="getProjectsList", | |
* tags={"Projects"}, | |
* summary="这是project简介", | |
* description="这是project描述", | |
* @OA\Response(response=200, description="successful operation", | |
* @OA\MediaType( | |
* mediaType="application/json", | |
* @OA\Schema( | |
* schema="DoctorDuty", | |
* type="object", | |
* required={""}, | |
* example={ | |
"data": { | |
{ | |
"id": 1, | |
"week_name": "周一", | |
"created_at": null, | |
"updated_at": null, | |
"days": { | |
{ | |
"id": 1, | |
"work_period": "上午8~12点", | |
"parent_id": 1, | |
"type": 1, | |
"created_at": null, | |
"updated_at": null | |
} | |
} | |
}}}, | |
* @OA\Property(property="id",type="integer",example="1",description="自增id"), | |
* @OA\Property(property="week_name",type="integer",example="周一",description="药店id"), | |
* @OA\Property(property="days",type="array",example="",description="每周下面的具体排期", | |
* @OA\Items( | |
* @OA\Property(property="type",type="integer",example="1",description="1表示工作时间2表示下班时间3表示任何时间"), | |
* @OA\Property(property="work_period",type="integer",example="1",description="描述上下班时间"), | |
* @OA\Property(property="parent_id",type="integer",example="1",description="周id"), | |
* @OA\Property(property="created_at",type="string",example="2020-01-15 13:22:57",description="添加时间"), | |
* @OA\Property(property="updated_at",type="string",example="2020-01-15 13:22:57",description="更新时间"), | |
* )), | |
* @OA\Property(property="created_at",type="string",example="2020-01-15 13:22:57",description="添加时间"), | |
* @OA\Property(property="updated_at",type="string",example="2020-01-15 13:22:57",description="更新时间") | |
* )), | |
* @OA\Response(response=400, description="Bad request"), | |
* ), | |
* security={ | |
* {"api_key_security_example": {}} | |
* }, | |
* ) | |
* | |
* Returns list of projects | |
*/ |
有童鞋问了老湿能不能再给力一点?
下面介绍如何定义通用parameter
// 定义公共参数医生端token并给出默认值 | |
/** | |
* @OA\Parameter( | |
* parameter="DoctorToken", | |
* description="医生token", | |
* name="Authorization", | |
@OA\Schema( | |
* type="string", | |
* default="Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOi8veXhob3NwaXRhbC5sb2NhbC9hcGkvbG9naW4iLCJpYXQiOjE1ODQ1MDA0NDQsImV4cCI6MTU5MjI3NjQ0NCwibmJmIjoxNTg0NTAwNDQ0LCJqdGkiOiJQYmtFWW5PR0NnUnVYZ1ZoIiwic3ViIjo4LCJwcnYiOiJlMTQ3ODdhYWI2NjY4OGNlMDZjNDcxMmU2NzNlMWExYzQ0ZjQ5MDk0IiwiZ3VhcmRfdHlwZSI6ImRvY3RvciJ9.iV8gItmly1yBspgkuQ-Z8KPuHXiw1PgehnJgce3xDHc", | |
* ), | |
* in="header", | |
* required=true, | |
* style = "simple", | |
* ) | |
*/ | |
// 引用公共参数 文档:https://zircote.github.io/swagger-php/Migrating-to-v3.html#rename-parameter-references/** | |
*@OA\Parameter(ref="#/components/parameters/DoctorToken"), | |
*/ |
有童鞋问了,Property
如果有重复的需要引入怎么办,下面介绍怎么定义一个property并且引入ref
上面介绍了如何引用公共返回值response
和parameter
下面介绍怎么定义公共property
// 定义一个property | |
/** | |
* The product name | |
* @var string | |
* | |
* @OA\Schema( | |
* schema="name", | |
* type="string", | |
* description="这是一个名字", | |
* example="王二小", | |
* ) | |
*/ | |
// 下面是引用 这样做是为啥呢,官网给的是DRY 文档:https://zircote.github.io/swagger-php/Getting-started.html#reusing-annotations-ref | |
/** | |
... | |
@OA\Property(ref="#/components/schemas/name",property="name"), | |
... | |
/* |
老湿:能不能再给力点:
// allOf将模型定义组合到新的模式组合中,可以用这种方法处理分页,因为所有的分页都是一样的 | |
/** | |
* @OA\Schema( | |
* schema="UpdateItem", | |
* allOf={ | |
* @OA\Schema(ref="#/components/schemas/DoctorDuty"), | |
* @OA\Schema( | |
* @OA\Property(property="idaaa", type="integer"), | |
* @OA\Property(property="namebbb", ref="#/components/schemas/name") | |
* ) | |
* } | |
* ) | |
*/ |
更多内容请根据文档学习,其实到这里我已经凌乱了~~~ 到此本文章已经完成(是不是非常简单?)