thinkphp结合swagger自动生成接口文档,附案例使用

一、swagger安装javascript

第一步:安装swagger-ui前端

去这里下载https://github.com/swagger-api/swagger-ui

下载完成以后,将文件夹放到你的网站根目录上面,例如我是放在我wamp下面的www目录。php

接着找到dist目录, 打开index.html把其中的那一串url改为本身的 好比http://localhost/tp/public/swagger.jsonhtml

注意这个url就是后面swagger.json 的路径;前端

若是你想支持中文在index.html中加上java

<script src='lang/translator.js' type='text/javascript'>

</script><script src='lang/zh-cn.js' type='text/javascript'></script>

而后打开URL输入http://localhost/swagger-ui/dist/index.html就能够看到前端界面了, 应该是没内容的, 由于还没生成swagger.json, 生成好以后你设置的URL就起了做用。swagger.json我是放在tp框架下的swagger-docs目录中的,具体路径看你本身,具体下面会提到,不要慌O(∩_∩)O~。laravel

第二步:安装swagger-php后端

进入你的项目目录执行以下命令:git

composer require zircote/swagger-php

提示安装完成后会在你tp项目的vendor中生成一个zircote的组件文件夹,说明已经安装插件成功了。github

第三步:生成swagger.json文件

方法一、直接在命令行中输入: php D:\Program\www\tp\vendor\zircote\swagger-php\bin\swagger D:\Program\www\tp\application\app\controller\ -o D:\Program\www\tp\public
注意:第一个路径是你安装成功后组件的路径;
第二个路径是你想要生成这个目录下全部用swagger方式注释的php文件,把全部注释生成api文档;
第三个路径是你存放生成swagger.json的路径

方法二、编写控制器方法生成swagger.json:web

若是咱们每次修改了api,还要手动执行第三步的代码,有些繁琐,那咱们就在控制器中写一个方法,每次访问swagger-ui的时候自动执行,而后跳转到前台swagger界面中。ajax

下面是控制器里面的方法


$path = '../application'; //你想要哪一个文件夹下面的注释生成对应的API文档
$swagger = \Swagger\scan($path);
//header('Content-Type: application/json');
//echo $swagger;
$swagger_json_path = $path.'/swagger-docs/swagger.json';
$res = file_put_contents($swagger_path, $swagger);
if ($res == true) {
$this->redirect('http://localhost/swagger-ui/dist/index.html');
}

 

第四步:编写swagger注释

控制器的注释写法

/**
 * @SWG\Resource(
 *  basePath="http://skyapi.dev",
 *  resourcePath="/vps",
 *  @SWG\Api(
 *   path="/vps",
 *   @SWG\Operation(
 *    method="GET",
 *    type="array",
 *    summary="Fetch vps lists",
 *    nickname="vps/index",
 *    @SWG\Parameter(
 *     name="expand",
 *     description="Models to expand",
 *     paramType="query",
 *     type="string",
 *     defaultValue="vps,os_template"
 *    )
 *   )
 *  )
 * )
 */
class VpsController extends Controller
{
    // ...
}

这只是个简单的实例具体的注释写法请本身百度

二、swagger注释使用

参考这个(写的比较全面):https://learnku.com/laravel/t/7430/how-to-write-api-documents-based-on-swagger-php#747b67

还有这个:https://blog.csdn.net/dyt19941205/article/details/79025266

这个:https://www.jianshu.com/p/554cd3762ab1

结合上面这几篇文章学习写了一个借口文档,也就四个方法,基本须要的东西都有了,之后再写文档能够照搬了

写接口文档真的很费时间,尤为写在php注释里,比较简单的文档可使用swagger提供的编辑工具,直接在上面修改json文件后导出使用就能够了:http://editor.swagger.io/

下面给一个完整的接口注释:

<?php namespace app\app\controller; use think\Controller; use think\Request; use think\Db; /** * @SWG\Swagger( * schemes={"http"}, * host="127.0.0.1", * basePath="/restudy/public/index.php/app/", * consumes={"multipart/form-data","X-Requested-With/XMLHttpRequest"}, * produces={"application/json"}, * @SWG\Info( * version="1.0", * title="个人测试学习api项目", * description="接口学习,目前只写了一个Api类,把顶级栏目接口、二级栏目接口、文章列表接口、文章内容接口写到了一块儿" * ), * * @SWG\Tag( * name="Api", * description="新闻webapp四大接口", * ), * ) */

class Api extends Controller { /** *@SWG\Get(path="/api/gettopnav", tags={"Api"}, * summary="获取顶级栏目列表", * description="获取顶级栏目列表,返回栏目id,名称,和是否启用栏目", @SWG\Parameter( * description="ajax请求要加上X-Requested-With:XMLHttpRequest头字段", * format="string", * in="header", * name="X-Requested-With", * required=true, * type="string", default="XMLHttpRequest", * * ), @SWG\Response(response="200", description="操做成功", @SWG\Schema( * required={""}, * @SWG\Property( * property="code", * type="integer", example=200, * ), * @SWG\Property( * property="msg", * type="string", example="顶级栏目返回成功", * ), @SWG\Property( * property="data", * type="object", example="[{cate_id:5,cate_name:'栏目1',cate_ison:1},{cate_id:6,cate_name:'栏目2',cate_ison:0}]", * ), * * )), @SWG\Response(response="201", description="数据为空", @SWG\Schema( * required={""}, * @SWG\Property( * property="code", * type="integer", example=201, * ), * @SWG\Property( * property="msg", * type="string", example="数据为空!", * ), * * )), @SWG\Response(response="400", description="非法请求,不是ajax请求", @SWG\Schema( * required={""}, * @SWG\Property( * property="code", * type="integer", example=400, * ), * @SWG\Property( * property="msg", * type="string", example="非法请求", * ), * * )), * ) */

    //顶级栏目接口
    public function getTopnav(){ if(request()->isAjax()){ $data=Db::table('re_cate')->where('cate_pid',0)->field('cate_id,cate_name,cate_ison')->select(); if(!empty($data)){ return json(['code'=>200,'msg'=>'顶级栏目返回成功','data'=>$data]); }else{ return json(['code'=>201,'msg'=>'数据为空!']); } }else{ return json(['code'=>400,'msg'=>'非法请求']); } } /** *@SWG\Post(path="/api/getsonnav", tags={"Api"}, * summary="获取二级栏目列表", * description="根据栏目id获取二级栏目列表,返回栏目id,名称,和是否启用栏目", @SWG\Parameter( * description="ajax请求要加上X-Requested-With:XMLHttpRequest头字段", * format="string", * in="header", * name="X-Requested-With", * required=true, * type="string", default="XMLHttpRequest", * * ), * @SWG\Parameter(name="id",type="integer", required=true, in="formData", * description="顶级栏目id" * ), @SWG\Response(response="200", description="操做成功", @SWG\Schema( * required={""}, * @SWG\Property( * property="code", * type="integer", example=200, * ), * @SWG\Property( * property="msg", * type="string", example="二级栏目返回成功", * ), @SWG\Property( * property="data", * type="object", example="[{cate_id:5,cate_name:'栏目1',cate_ison:1},{cate_id:6,cate_name:'栏目2',cate_ison:0}]", * ), * * )), @SWG\Response(response="201", description="数据为空", @SWG\Schema( * required={""}, * @SWG\Property( * property="code", * type="integer", example=201, * ), * @SWG\Property( * property="msg", * type="string", example="数据为空!", * ), * * )), @SWG\Response(response="400", description="非法请求,不是ajax请求", @SWG\Schema( * required={""}, * @SWG\Property( * property="code", * type="integer", example=400, * ), * @SWG\Property( * property="msg", * type="string", example="非法请求", * ), * * )), * ) */

    //二级栏目接口
    public function getSonnav(){ if(request()->isAjax()){ $cate_id=input('id'); $data=Db::table('re_cate')->where('cate_pid',$cate_id)->field('cate_id,cate_name,cate_ison')->select(); if(!empty($data)){ return json(['code'=>200,'msg'=>'二级栏目返回成功','data'=>$data]); }else{ return json(['code'=>201,'msg'=>'无二级栏目']); } }else{ return json(['code'=>400,'msg'=>'非法请求']); } } /** *@SWG\Post(path="/api/getarticlelist", tags={"Api"}, * summary="获取文章列表", * description="根据栏目id获取文章列表(须要参数:栏目id,页码,一页显示文章数量)", @SWG\Parameter( * description="ajax请求要加上X-Requested-With:XMLHttpRequest头字段", * format="string", * in="header", * name="X-Requested-With", * required=true, * type="string", default="XMLHttpRequest", * * ), * @SWG\Parameter(name="id",type="integer", required=true, in="formData", * description="栏目id" * ), @SWG\Parameter(name="p",type="integer", required=true, in="formData", * description="页码" * ), @SWG\Parameter(name="num",type="integer", required=true, in="formData", * description="每页文章数量" * ), @SWG\Response(response="200", description="操做成功", @SWG\Schema( * required={""}, * @SWG\Property( * property="code", * type="integer", example=200, * ), * @SWG\Property( * property="msg", * type="string", example="文章列表返回成功", * ), @SWG\Property( * property="data", * type="object", example="{total:null,per_page:5,current_page:1,last_page:null,data:[{ar_id:1,cate_id:10,ar_title:'文章标题一',ar_keywords:'文章关键字',ar_pic:'url',ar_content:'文章内容',ar_ison:1}]}", * ), * * )), @SWG\Response(response="201", description="数据为空", @SWG\Schema( * required={""}, * @SWG\Property( * property="code", * type="integer", example=201, * ), * @SWG\Property( * property="msg", * type="string", example="数据为空!", * ), * * )), @SWG\Response(response="400", description="非法请求,不是ajax请求", @SWG\Schema( * required={""}, * @SWG\Property( * property="code", * type="integer", example=400, * ), * @SWG\Property( * property="msg", * type="string", example="非法请求", * ), * * )), * ) */
    //指定栏目文章列表(须要参数:栏目id,页码,一页显示文章数量)
    /* 返回json格式 { "code": 200, "msg": "文章返回成功", "data": { "total": null, "per_page": "1", "current_page": 1, "last_page": null, "data": [ { "ar_id": 1, "cate_id": 10, "ar_title": "title", "ar_keywords": "k,e,y", "ar_pic": "public/static/uploads/20190902\\98edeb3d27fe4342da8b07d5ae3e98de.jpg", "ar_content": "<p>内容<br/></p>", "ar_ison": 1 } ] } } */
    public function getArticlelist(){ if(request()->isAjax()){ $cate_id=input('id'); $page=input('p'); $number=input('num'); $data=Db::table('re_article')->where('cate_id',$cate_id)->paginate($number,true,['page'=>$page]); if(!empty($data)){ return json(['code'=>200,'msg'=>'文章返回成功','data'=>$data]); }else{ return json(['code'=>201,'msg'=>'没有数据了']); } }else{ return json(['code'=>400,'msg'=>'非法请求']); } } /** *@SWG\Post(path="/api/getarticlecontent", tags={"Api"}, * summary="获取文章内容", * description="根据文章id获取文章信息", @SWG\Parameter( * description="ajax请求要加上X-Requested-With:XMLHttpRequest头字段", * format="string", * in="header", * name="X-Requested-With", * required=true, * type="string", default="XMLHttpRequest", * * ), * @SWG\Parameter(name="id",type="integer", required=true, in="formData", * description="文章id" * ), @SWG\Response(response="200", description="操做成功", @SWG\Schema( * required={""}, * @SWG\Property( * property="code", * type="integer", example=200, * ), * @SWG\Property( * property="msg", * type="string", example="文章返回成功", * ), @SWG\Property( * property="data", * type="object", example="{ar_id:1,ar_title:'文章1',ar_pic:'url',ar_keywords:'文章关键字',ar_content:'文章内容',ar_ison:1}", * ), * * )), @SWG\Response(response="201", description="数据为空", @SWG\Schema( * required={""}, * @SWG\Property( * property="code", * type="integer", example=201, * ), * @SWG\Property( * property="msg", * type="string", example="数据为空!", * ), * * )), @SWG\Response(response="400", description="非法请求,不是ajax请求", @SWG\Schema( * required={""}, * @SWG\Property( * property="code", * type="integer", example=400, * ), * @SWG\Property( * property="msg", * type="string", example="非法请求", * ), * * )), * ) */
    //获取指定文章内容
     public function getArticlecontent(){ if(request()->isAjax()){ $ar_id=input('id'); $data=Db::table('re_article')->where('ar_id',$ar_id)->find(); if(!empty($data)){ return json(['code'=>200,'msg'=>'文章返回成功','data'=>$data]); }else{ return json(['code'=>201,'msg'=>'无此文章']); } }else{ return json(['code'=>400,'msg'=>'非法请求']); } } }