Swagger 构建项目中Api文档

作为一个后端程序员,在编辑后台接口时,我们可以有多种选择,当然在此之前介绍过apidocJs,这里再介绍一个目前在用的接口管理工具Swagger

简介

在后端提供的前端的接口时,以前可能以一分md形式的文档提供给前端,现在开发对于前后台的交互很是常见,在编写我们后台的文档时,再遵循一定的规范即OpenAPI规范,根据这样的规范我们可以更加准确快速的描述API
而和swagger这些文档描述一样 ,你可以理解成一种独立与程序语言的注释性语言,因为他们不会随着最后程序而编译,而是单独的独立出来,根据自身的解释器而转换成一种格式文档,最后再加以渲染,比如swaggerswagger-ui渲染之后,前端程序员就可以直观的指导API的作用,并提供了交换测试的方式,这样的话很是方便
swagger具有十分庞大的生态系统,几乎支持所有的编程语言,对于这样的交互式的API文档对于开发者来说是很好的福音

使用

这里以laravel项目为例,对于swagger已有先人帮我们集成好了,这里我们使用的是zircote/swagger-php,和laravel的扩展一样通过composer安装

1
$ composer require zircote/swagger-php

安装完毕之后 我们可以在应用的目录App/Http下新建Api目录用来存放我们的Api接口

新建一个BaseController来写基本的返回信息格式 当然在这个控制器里也会标注我们接口的版本信息

BaseController里去定义接口的版本等信息

1
2
3
4
5
6
7
8
9
10
11
12
/**
* @SWG\Swagger(
* host="www.geekghc.com",
* schemes={"http", "https"},
* basePath="/api/",
* @SWG\Info(
* version="1.0.0",
* title="codespace API文档",
* description="codespace community description...",
* )
* )
*/

这里指明了host version title description这些描述信息 在接下来的接口类中都会继承这个父类

在解释器最终形成文档时也只会去解析这样的非代码的解释语言 最终就是得我们的API文档

在这里我们最终生成的是json组成的文件信息,那么如果只是这样留给我们的前端相比会一脸懵逼,作为接口文档我们

希望其他人可以在线执行模拟接口信息并提供一定的UI这样看起来才是友好的

接下来新建一个路由用来展示最终的Api文档

1
2
3
4
5
6
7
8
//api文档
Route::get('/api/docs',function(){
return view('apidoc');
});
//api文档json
Route::get('get/swagger', ['middleware' => 'auth', function () {
echo file_get_contents('./swagger.json');
}]);

第一个api/docs用来返回我我们的view视图 最后需要呈现的是一个UI的接口文档 因此我们需要引入swagger-ui来丰富我们的界面

这里返回的视图为apidoc.blade.php 首先定义好文档的用户名和密码 这样方便为内部使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
define('ADMIN_USERNAME','admin'); // Admin Username
define('ADMIN_PASSWORD','ghc1996'); // Admin Password
if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW']) ||
$_SERVER['PHP_AUTH_USER'] != ADMIN_USERNAME ||$_SERVER['PHP_AUTH_PW'] != ADMIN_PASSWORD) {
Header("WWW-Authenticate: Basic realm=\"Memcache Login\"");
Header("HTTP/1.0 401 Unauthorized");

echo <<<EOB
<html><body>
<h1>Rejected!</h1>
<big>Wrong Username or Password!</big>
</body></html>
EOB;
exit;
}
?>

至于swagger-ui可以直接去官网https://swagger.io/swagger-ui/进行下载
在文件中继续引入必要的cssjs文件即可 这里的详情我放在gist上 请自行查看

##Swagger结合项目
之前都是安装的准备工作,接下来结合到具体的项目里,这里我以我其中的一个项目为例:

首先介绍一下OpenAPI规范。OpenAPI是Linux基金会的一个项目。试图通过定义一种用来描述API格式或API定义的语言,来规范RESTful服务开发过程。OpenAPI规范帮助我们描述一个API的基本信息,比如:

  • 有关该API的一般性描述
  • 可用路径(/资源)
  • 在每个路径上的可用操作(获取/提交…)
  • 每个操作的输入/输出格式

在实际项目中 对于接口的基类 这里放在BaseController我们定义swagger的基本组成部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* @SWG\Swagger(
* swagger="2.0",
* host="codespace.example",
* schemes={"http", "https"},
* basePath="/api/",
* @SWG\Info(
* version="1.0.1",
* title="codespace API文档",
* description="codespace system description...",
* ),
* @SWG\Tag(name="User", description="用户"),
* @SWG\Tag(name="Post", description="动态"),
* @SWG\Tag(name="Article", description="文章"),
* @SWG\Tag(name="Message", description="消息"),
* @SWG\Tag(name="Article", description="标签"),
* @SWG\Tag(name="Comment", description="评论"),
* @SWG\Tag(name="Action", description="用户互动操作"),
* @SWG\Tag(name="Comment", description="侧边栏"),
* @SWG\Tag(name="Setting", description="用户设置"),
*
* )
*/

这里首先通过swagger属性来申明OpenAPI 规范的版本。

1
2
3
4
5
6
<?php
/**
* @SWG\Swagger(
* swagger="2.0"
* )
*/

接下来就是接口文档的地址和给开发者的URL地址 这里还定义了接口地址的前缀

1
2
3
*   host="codespace.example",
* schemes={"http", "https"},
* basePath="/api/",

接下来就是接口文档的描述信息 这其中包含了标题、版本和描述信息

1
2
3
4
5
*   @SWG\Info(
* version="1.0.1",
* title="codespace API文档",
* description="codespace system description...",
* ),

为了实际的接口分类 这里引入了Tag的概念 这在每个接口申明时可以对其进行归并分类

1
2
3
*   @SWG\Tag(name="User", description="用户"),
* @SWG\Tag(name="Post", description="动态"),
* @SWG\Tag(name="Article", description="文章"),

定义完毕基类中的接口基本信息后我们可以尝试着去书写详细的接口信息 以用户为例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
* 当前用户
* @SWG\Get(
* tags={"User"},
* path="/user",
* operationId="UserController",
* summary="当前用户",
* description="当前用户",
* produces={"application/json"},
* @SWG\Parameter(
* name="id",
* in="query",
* description="用户id",
* required=true,
* type="string",
* ),
* @SWG\Response(
* response=200,
* description="当前用户",
* @SWG\Schema(
* type="array",
* example={"errcode":"响应代码","data":{{"name":"项目名称","logo":"项目封面","creatorId":"项目拥有者id","status":"0 删除 | 1 活动","updated_at":"项目修改时间","isArchived":"是否归档 true 归档 false 未归档","created_at":"项目添加时间","creator": {"uid": "项目拥有者id","full_name": "项目拥有者姓名","avatar": "项目拥有者头像"}}},"errmsg":"响应信息"}
* )
* )
* )
*/

这里将当前用户的这个接口归并为User这个Tag 同时也包含了url地址、请求方式、操作控制器、说明这些属性信息
Parameter里申明请求参数 这里需要的是用户的id,in申明请求体类型 当然如果是post请求 这里的方式应该为formData

有了请求的参数定义当然也需要有返回值得定义 在Response体里返回对应的数据体

这里只是以一个小的用户信息接口为例 在每个接口方法中可以对应着不同的接口请求和返回 而这些也基本都是大同小异

最后完成了接口文档的编写 在此之前说过最后我们需要将所有的接口描述生成到一个json文件中再通过semantic-ui渲染的界面呈现给前端开发者

这里的生成命令为

1
$ php ./vendor/zircote/swagger-php/bin/swagger ./app/Http/Controllers/Api -o ./public

也就是说将./app/Http/Controllers/Api路径下的所有API的控制文件的接口信息生成到public目录

最后的结果访问api/doc就是这样的
1

相关链接