Laravel(PHP)使用Swagger生成API文档不彻底指南 - 基本概念和环境搭建 - 简书

PHPer中,不少人据说过Swagger,部分人知道Swagger是用来作API文档的,然而只有少数人真正知道怎么正确使用Swagger,由于PHP界和Swagger相关的资料实在是太少了。因此鄙人斗胆一试,但愿能以本文帮助到你们了解Swagger,今后告别整天用WordMarkdown折腾API文档的日子。javascript

什么是Swagger

Swagger is a simple yet powerful representation of your RESTful API. With the largest ecosystem of API tooling on the planet, thousands of developers are supporting Swagger in almost every modern programming language and deployment environment. With a Swagger-enabled API, you get interactive documentation, client SDK generation and discoverability.php

Swagger是一种简单、强大的RESTful API表现形式。
其拥有地球上最大的API工具生态环境,无数程序员在几乎全部主流语言和开发环境中添加了对Swagger的支持。
只要你的API添加对Swagger的支持,你就等于拥有了可交互的API文档,SDK代码生成以及外部使用友好的API。html

  • Swagger.io首页

写了这么一堆貌似很屌的话,因此……Swagger究竟是个啥?是一套代码仍是一个软件呢?前端

其实和官网高度归纳的描述同样,Swagger是一种通用的、和编程语言无关的API的描述规范。只要开发者在本身的API之上添加符合Swagger规范的描述,就能利用上Swagger丰富的生态,找到符合本身开发语言的工具去作不少事:好比最经常使用的生成API文档,或者生成返回假数据的服务端基础代码等等。java

人类的文字即是一种规范,人理解了文字的规范就能够进行阅读,机器按照规范也能够进行文字识别,武林秘籍能够写成文字让全部人练习,人的思想也能够写成文字进行传播。人类的不少经典书籍都被翻译成了多国文字,Swagger的描述一样也支持用YAMLXMLJSON来表示,含义都是一致的。Swagger UI经过任意一种形式的Swagger描述信息就能渲染出酷炫的API文档,服务端接口代码生成工具也能经过这个描述信息生成Controller代码,围绕着Swagger,一个强大的API生态环境就出现了。git

那么就是说,之前我用Markdown写文档,如今我用YAML/XML/JSON写文档就好了?程序员

是的,但Swagger功能不止如此。使用Swagger能够分为两种状况:github

  1. 项目未开始,须要先定义好API使前端和后端可以同时开发;编程

  2. API已完成,须要提供文档;json

第二种状况,咱们确实能够直接开始编写一个JSON或者YAML文件来描述现有的API(使用Swagger-Editor),不过这里咱们主要介绍第一种状况,全方位感觉Swagger

继续以前,咱们先介绍一下另外一个东西(也许这么多新概念就是把你们弄晕了的缘由……找到Swaager的应用最佳实践须要一点点时间,请继续看)。

Annotation

AnnotationJava引入的一个概念,简单来讲就是用来给对应的源代码添加额外的元数据(关于数据的更详细的数据)的一种语法。Annotation自己不影响代码的执行,只能经过额外的工具解析或执行,一般用来提供代码检查、数据类型标注等功能。因为Annotation的强大,不少编程语言都引入了这个概念,包括PHP

那么,若是咱们能将Swagger的描述用Annotation的方式直接写在Controller上,岂不是既方便又好维护?

结合Swagger和PHP

PHP中使用Swagger,咱们须要一个工具去编写和解析AnnotationSwagger的描述(例如JSON形式),Swagger丰富的生态不是吹的,这里咱们直接使用前人写好的swagger-php。而编写API咱们则使用Laravel框架(5.1)。固然,swagger-php自己和用哪一种框架开发是不要紧的。

首先在Laravel项目中安装swagger-php

$ composer require zircote/swagger-php

接着定义一个Controller用来测试:

$ artisan make:controller SwaggerController --plain

Controller中加上两个方法:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Requests;
use App\Http\Controllers\Controller;

class SwaggerController extends Controller
{
    /**
     * 返回JSON格式的Swagger定义
     */
    public function getJSON()
    {

    }

    /**
     * 假设是项目中的一个API
     */
    public function getMyData()
    {

    }

}

相应的,咱们增长路由配置:

<?php

Route::group(['prefix' => 'swagger'], function () {
    Route::get('json', 'SwaggerController@getJSON');
    Route::get('my-data', 'SwaggerController@getMyData');
});

咱们先实现getJSON方法,使其可以返回合法的Swagger定义:

<?php

// ...

    /**
     * 返回JSON格式的Swagger定义
     *
     * 这里须要一个主`Swagger`定义:
     * @SWG\Swagger(
     *   @SWG\Info(
     *     title="个人`Swagger`API文档",
     *     version="1.0.0"
     *   )
     * )
     */
    public function getJSON()
    {
        // 你能够将API的`Swagger Annotation`写在实现API的代码旁,从而方便维护,
        // `swagger-php`会扫描你定义的目录,自动合并全部定义。这里咱们直接用`Controller/`
        // 文件夹。
        $swagger = \Swagger\scan(app_path('Http/Controllers/'));

        return response()->json($swagger, 200);
    }

// ...

访问一下/swagger/json,若是咱们看到下面的返回就说明搭建成功了:

{"swagger":"2.0","info":{"title":"\u6211\u7684`Swagger`API\u6587\u6863","version":"1.0.0"},"paths":{},"definitions":{}}

而后咱们来定义项目中的API接口:

<?php 

// ...

    /**
     * 假设是项目中的一个API
     *
     * @SWG\Get(path="/swagger/my-data",
     *   tags={"project"},
     *   summary="拿一些神秘的数据",
     *   description="请求该接口须要先登陆。",
     *   operationId="getMyData",
     *   produces={"application/json"},
     *   @SWG\Parameter(
     *     in="formData",
     *     name="reason",
     *     type="string",
     *     description="拿数据的理由",
     *     required=true,
     *   ),
     *   @SWG\Response(response="default", description="操做成功")
     * )
     */
    public function getMyData()
    {
        //todo 待实现
    }

// ...

虽然API尚未真正实现,可是咱们的第一个API文档已经完成了(后面咱们在讲每一个Annotation的含义)!来看看如今JSON接口的输出内容:

{"swagger":"2.0","info":{"title":"\u6211\u7684`Swagger`API\u6587\u6863","version":"1.0.0"},"paths":{"\/swagger\/my-data":{"get":{"tags":["project"],"summary":"\u62ff\u4e00\u4e9b\u795e\u79d8\u7684\u6570\u636e","description":"\u8bf7\u6c42\u8be5\u63a5\u53e3\u9700\u8981\u5148\u767b\u5f55\u3002","operationId":"getMyData","produces":["application\/xml","application\/json"],"parameters":[{"name":"reason","in":"formData","description":"\u62ff\u6570\u636e\u7684\u7406\u7531","required":true,"type":"string"}],"responses":{"default":{"description":"\u64cd\u4f5c\u6210\u529f"}}}}},"definitions":{}}

Swagger-UI

固然,若是直接把这个甩给前端同窗,他们必定会一脸懵逼看着你的……为了把JSON定义转化为能够阅读和交互的API,咱们还须要用到Swagger-UISwagger-UI是一套不依赖后端的纯HTML程序,只须要将以前输出JSON的接口地址给它,就能获得一个强大的API文档了。为了不请求跨域问题,咱们将Swagger-UI部署在项目的public/swagger-ui/文件夹中。安装很是简单,直接在GitHub上下载压缩包,解压缩以后将dist/文件夹下的全部内容放到public/swagger-ui/就好了。

在访问以前,咱们先改一下Swagger-UI默认请求的接口地址,打开public/swagger-ui/index.html,找到如下代码:

<script type="text/javascript">
    $(function () {
        var url = window.location.search.match(/url=([^&]+)/);
        if (url && url.length > 1) {
          url = decodeURIComponent(url[1]);
        } else {
          url = "http://petstore.swagger.io/v2/swagger.json"; // 就是这一行
        }

// ...

url改为咱们本身接口的地址,例如http://my.project/swagger/json。打开浏览器,访问/swagger-ui/,就能看到API文档了:


高大上的界面

在这个高大上的API文档上稍微玩一下子,你可能冒出几个问题:

  • 有没有中文支持?

  • 每次都要点一次才能展开API列表好麻烦,能默认展开吗?

  • 右下角那个ERROR是什么意思?

可能你还有更多问题,但咱们先说这三个吧…

设置中文

Swagger-UI支持多国语言,仍是打开swagger-ui/index.html,大约在30行左右:

// ...

    <!-- Some basic translations -->
    <!--<script src='lang/translator.js' type='text/javascript'></script>-->
    <!--<script src='lang/ru.js' type='text/javascript'></script>-->
    <!-- <script src='lang/en.js' type='text/javascript'></script> -->

// ...

咱们改成:

// ...

    <!-- Some basic translations -->
    <script src='lang/translator.js' type='text/javascript'></script>
    <script src='lang/zh-cn.js' type='text/javascript'></script>

// ...

这样就会变成中文了:


亲切的中文界面

API列表默认展开

大概在swagger-ui/index.html的74行左右有如下代码:

// ...

    onFailure: function(data) {
      log("Unable to Load SwaggerUI");
    },
    docExpansion: "none", // 这一行就是用来设置文档默认展开层级的
    jsonEditor: false,

// ...

这个配置有三个值:

  • none 折叠全部内容

  • list 展开全部分组的API列表

  • full 展开全部分组的API列表以及每一个API的请求细节

通常来讲设置为list就能够了。

去掉ERROR提示

Swagger-UI默认会将你的接口JSON传给swagger.io进行格式验证,而后对于咱们已经使用了swagger-php的项目来讲基本不须要(由于写错了Annotation的话会形成Swagger JSON接口报错),并且内部项目有时也不方便暴露,因此咱们能够关闭验证功能来去除右下角的ERROR提示图标。这个配置并不存在于swagger-ui/index.html中,咱们须要手动在Swagger UI声明时设置一个新参数:

// ...

    window.swaggerUi = new SwaggerUi({
        // ...

        validatorUrl: null, //添加这个配置
    });

// ...

再次刷新以后验证提示就完全消失了。

若是你须要这个验证提示,但又不想使用swagger.io的公用服务,你也能够本身搭建一个,点这里查看Swagger Validator Badge的使用方法

折腾成果


折腾后的成果

自定义Swagger UI

Swagger UI自己提供了不少配置和参数供用户自定义,点这里查看,你们能够随意发挥。

待续

下次再写关于swagger-php的使用细节。

延伸阅读

在PHP中写复杂的Swagger定义时如何偷懒(基于zircote/swagger-php)

相关文章
相关标签/搜索