前端swagger-ui部署:
背景:
swagger-php项目的Example中已经有了很多相关例子,照着复制粘贴就可以了.更具体的相关注释规则的文档,看这里:http://bfanger.nl/swagger-exp...
swagger的response编写规则是按照http的responsecode来的(404,401等),总之对我们的接口来说,这套描述规则不好用.
我的接口栗子里都没有写response规则,是因为我们用json作为返回载体,返回错误码也是包含在这个json结构体里.并且多数接口返回的json格式都很复杂,用swagger的response规则基本没法描述.
我给这个文件取名叫Swagger.php,大体内容如下:
以后大家就在这里愉快的对接口把!
以后大家就在这里愉快的对接口把!
以后大家就在这里愉快的对接口把!
'
* ),
*
* @SWGTag(
* name='User',
* description='用户操作',
* ),
*
* @SWGTag(
* name='MainPage',
* description='首页模块',
* ),
*
* @SWGTag(
* name='News',
* description='新闻资讯',
* ),
*
* @SWGTag(
* name='Misc',
* description='其他接口',
* ),
* )
*/
NOTE:swagger-php只是个工具,放在哪里都可以.
-c选项表示如果账号文件(api_project_accounts.d不存在,则新建之.因此创建第一个账号时一定要加-c,之后创建则一定不要再加--b参数表示明文指定密码,就是上面第一条和第二条命令中最后一个输入(password_for_admin,12345.因此如果不想明文指定,可以不加-b,像上面的第三条命令,就会和sudo命令一样,让你输入一段看不见的密码.上面命令创建了三个账号,admin,liuxu,xiaoming,并将账号密码保存在api_project_accounts.db文件中.
首先用htpasswd命令,为需要访问文档的同学生成帐号名和密码:
$ htpasswd -cb your/path/to/api_project_accounts.db admin password_for_admin
$ htpasswd -b your/path/to/api_project_accounts.db liuxu 123456
$ htpasswd your/path/to/api_project_accounts.db xiaoming
前提:项目为git项目.项目部署以git为基础.原理:使用git的hook机制在适当节点执行文档生成命令.时机:有两种:如果使用git部署项目,则可以在部署时自动生成;如果不是,也可以考虑在gitcommit时自动生成.步骤:
php /path/to/swagger-php/bin/swagger /project_path/app/controllers/ -o /project_path/swagger/docs/
遇到的问题
部署方法很简单,就三步:
var url = window.location.search.match(/url=([^&]+)/);
if (url && url.length > 1) {
url = decodeURIComponent(url[1]);
} else {
url = 'http://api.my_project.com/dist/swagger.json';
}
# 把 swagger-php_dir 这个,换成你的 swagger-php 录即可
cp swagger-php_dir/json_docs/swagger.json php_api_project/dist/
跨域问题:
记得改完了重启nginx:
常用字段简要说明
说是部署,主要就是产生bin/swagger这个用来生成swagger.json文件的命令.主要工作,就是用composer解决下依赖就可以了.因为国内直接用composer比较蛋疼,所以最好设置下国内的那个composer源.这样的话,整个文档生成工具的部署就是下面三行命令:
$ cd swagger-php
$ composer config repo.packagist composer https://packagist.phpcomposer.com
$ composer update
上面login接口中用到了两个有结构的数据,一个是image类型的数组,一个是video类型的结构.(其实结构化的参数只能在in='body'时才可以用,但这并不妨碍我们为了简化问题,把结构化数据格式化为json当字符串传递.我们只要将这种结构展现在文档里就可以了)
如此,则每次该项目代码执行gitpull命令时,swagger文档将会自动更新.
上述步骤完成后,访问http://apmy_project.com/dis...就可以看到Examples那个小项目的api文档了.
此段写于2018-04-2本文其他段落成于2017-01-1方法仅限git项目.今天有朋友问phpswagger的使用方法,又审了一遍此文,才发现没有写自动生成这部分.每次更新项目还要手动生成文档的话,就太麻烦了.这种操作岂能不自动化.方法如下:
如上所示,我的这个php文件一行php代码也没有,就只有注释,为了定义一些全局的swagger设置:
搭建
先说下最终的文档生成流程会是什么样子,以便先有个整体的认识:搭建完成后,整个流程,从文档生成到前端展现,大体如下:
大家应该已经看出来了,其实接口的注释不一定要写在接口上,凭空写注释,一样能生成文档.所以不必纠结各个注释放在什么地方.比如swagger整体定义,tag定义等,写在任意可以被扫描到的php文件中就可以了.
实现此需求只需要swagger的如下两个项目:swagger-php:扫描php注释的工具.内含一个不错的例子.swagger-ui:用以将扫描工具生成的swagger.json文件内容展示在网页上.
好吧,上面那行命令是为了一眼可以看出这行命令是做什么的.但它有个坏处,就是要把项目的绝对路径写死在脚本里,这样这个脚本就不具有通用性.上面这行命令可以更新为下面的这行等价命令:
proj_root=$(readlink -f $(dirname $(git rev-parse --git-dir))) &&
php /path/to/swagger-php/swagger-php/bin/swagger $proj_root/app/controllers/ -o $proj_root/swagger/docs/
首先将这两个项目下载到本地:
$ git clone https://github.com/swagger-api/swagger-ui.git
$ git clone https://github.com/zircote/swagger-php.git
这里只是自己理解加翻译的简要说明,更详细的字段说明,还是要去看文档.再次贴出文档:http://bfanger.nl/swagger-exp...
规则简单明了,看着代码大家就都懂了.不懂的话,去看文档吧...
如果要将文档放在公网,直接暴露自己的接口可不太合适.因此要给文档的访问地址做鉴权.因为安全性要求不高,并且公司较小开发组人员不多,我就直接用了nginx提供的httpbasicauth做了登录鉴权.老规矩,先贴官方文档:https://www.nginx.com/resour..这样做鉴权很简单,分分钟搞定.不详述,就两步:
那么直接把上面这句命令放在对应的项目中的.git/hooks/post-update脚本中即可,如没有则新建.
因此我就直接舍弃了response描述,直接用swagger就地请求接口看看返回了什么就是.再不行就把接口的返回信息在description里大体描述一下.
接口描述(@SWGGet,@SWGPost等)常用字段:
summary - string
接口的简要介绍,会显示在接口标头上,不能超过120个字符
description - string
接口的详细介绍
externalDocs - string
外部文档链接
operationId - string
全局唯一的接口标识
consumes - [string]
接口接收的MIME类型
produces - [string]
接口返回的MIME类型,如 application/json
schemes - [string]
接口所支持的协议,取值仅限: 'http', 'https', 'ws', 'wss'
parameters - [Parameter Object | Reference Object]
参数列表
这种有结构的东西swagger也可以用php注释定义:
编写PHP注释
然后在nginx的项目配置中给自己的这个访问地址开启httpbasicauth就可以了.
location /dist {
auth_basic 'my api project login';
auth_basic_user_file your/path/to/api_project_accounts.db;
}
参数描述(@SWGParameter)常用字段:
name - string
参数名. 通过路径传参(in 取值 'path')时有注意事项,没用到,懒得看了...
in - string
参数从何处来. 必填. 取值仅限: 'query', 'header', 'path', 'formData', 'body'
description - string
参数描述. 最好别太长
type - string
参数类型. 取值仅限: 'string', 'number', 'integer', 'boolean', 'array', 'file'
required - boolean
参数是否必须. 通过路径传参(in 取值 'path')时必须为 true.
default - *
默认值. 在你打算把参数通过 path 传递时规矩挺多,我没用到.用到的同学自己看文档吧.
swagger牛X的地方就是它可以在文档上就地访问接口并展示输出,对于调试和对接口非常的方便.但如果不想将swagger-ui部署在接口项目下,那么在swagger-ui就地访问接口时,就会因跨域问题而请求不到结果.(ResponseHeaders:noresponsefromserver;ResponseBody:nocontent).这里不讲跨域问题怎么解决,只是给遇到上面的问题的各位一个思路,知道错误是由跨域产生的,就好解决了.
这样做的好处是,在接口参数文档中,这个结构会被展示出来,这样客户端同学就知道该传什么结构了.
如果系统里没有htpass这个命令,可以安装apache的httpd服务器软件,htpass这个命令就包含在其中:
登录鉴权:
自动生成文档
然后就是给每个接口编写swagger格式的注释了.还是举个栗子吧:
/**
* @SWGPost(path='/user/login', tags={'User'},
* summary='登录接口(用户名+密码)',
* description='用户登录接口,账号可为 用户名 或 手机号. 参考(这个会在页面产生一个可跳转的链接: [用户登录注意事项](http://blog.csdn.net/liuxu0703/)',
* @SWGParameter(name='userName', type='string', required=true, in='formData',
* description='登录用户名/手机号'
* ),
* @SWGParameter(name='password', type='string', required=true, in='formData',
* description='登录密码'
* ),
* @SWGParameter(name='image_list', type='string', required=true, in='formData',
* @SWGSchema(type='array', @SWGItems(ref='#/definitions/Image')),
* description='用户相册. 好吧,没人会在登录时要求填一堆图片信息.这里是为了示例 带结构的数据, @SWGSchema ,这个结构需要另行定义,下面会讲.'
* ),
* @SWGParameter(name='video', type='string', required=true, in='formData',
* @SWGSchema(ref='#/definitions/Video'),
* description='用户 呃... 视频? 同上,为了示例 @SWGSchema .'
* ),
* @SWGParameter(name='client_type', type='integer', required=false, in='formData',
* description='调用此接口的客户端类型: 1-Android, 2-IOS. 非必填,所以 required 写了 false'
* ),
* @SWGParameter(name='gender', type='integer', required=false, in='formData',
* default='1',
* description='性别: 1-男; 2-女. 注意这个参数的default上写的不是参数默认值,而是默认会被填写在swagger页面上的值,为的是方便用swagger就地访问该接口.'
* ),
* )
*/
public function loginAction() {
// php code
}
/**
* @SWGGet(path='/User/myWebPage', tags={'User'},
* produces={'text/html'},
* summary='用户的个人网页',
* description='这不是个api接口,这个返回一个页面,所以 produces 写了 text/html',
* @SWGParameter(name='userId', type='integer', required=true, in='query'),
* @SWGParameter(name='userToken', type='string', required=true, in='query',
* description='用户令牌',
* ),
* )
*/
public function myWebPageAction(){
// php code
}
为客户端同事写接口文档的各位后端同学,已经在各种场合回忆了使用自动化文档工具前手写文档的血泪史.我的故事却又不同,因为首先来说,我在公司是Android组负责人,属于上述血泪史中催死人不偿命的客户端阵营.但血泪史却是相通的,没有自动化文档的日子,对接口就是开发流程中最低效的环节.因此决定使用swagger搭建由php注释生成文档的流程.
文档生成工具部署
schemes:使用协议(可以填多种协议)host:项目地址,这个地址会作为每个接口的urlbase,拼接起来一期作为访问地址consumes:接口默认接收的MIME类型,我的例子中的formData对应post表单类型.注意这是项目默认值,在单个接口注释里可以复写这个值.produces:接口默认的回复MIME类型.api接口用的比较多的就是application/json和application/xm@SWGInfo:这个里面填写的东西,会放在文档的最开头,用作文档说明.@SWGTag:tag是用来给文档分类的,name字段必须唯某个接口可以指定多个tag,那它就会出现在多组分类中.tag也可以不用在这里预先定义就可以使用,但那样就没有描述了.多说无益,稍微用用就啥都明白了.
这样当这两个类也被swagger-php/bin/swagger扫描到后,其他地方就可以正确引用到Image和Video为名字的这两个结构体了.
文章为作者独立观点,不代表观点