Lumen微服務生成Swagger文檔

Xnip2019-01-02_16-07-57

作爲一名phper,在使用Lumen框架開發微服務的時候,API文檔的書寫總是少不了的,比較流行的方式是使用swagger來寫API文檔,但是與Java語言原生支持 annotation 不同,php只能單獨維護一份swagger文檔,或者在註釋中添加annotations來實現類似的功能,但是註釋中書寫Swagger註解是非常痛苦的,沒有代碼提示,沒有格式化。

本文將會告訴你如何藉助phpstorm中annotations插件,在開發Lumen微服務項目時(Laravel項目和其它php項目方法類似)快速的在代碼中使用註釋來創建swagger文檔。

本文將會持續修正和更新,最新內容請參考我的 GITHUB 上的 程序猿成長計劃 項目,歡迎 Star,更多精彩內容請 follow me

框架配置

我們使用當前最新的 Lumen 5.7 來演示。演示代碼放到了github,感興趣的可以參考一下

https://github.com/mylxsw/lumen-swagger-demo

安裝依賴

在Lumen項目中,首先需要使用 composer 安裝SwaggerLume項目依賴

composer require darkaonline/swagger-lume

-w568

項目配置

bootstrap/app.php文件中,去掉下面配置的註釋(大約在26行),啓用Facades支持。

$app->withFacades();

啓用SwaggerLume 項目的配置文件,在 Register Container Bindings部 分前面,添加

$app->configure('swagger-lume');

然後,在 Register Service Providers 部分,註冊 SwaggerLume 的ServiceProvider

$app->register(\SwaggerLume\ServiceProvider::class);

在項目的根目錄,執行命令 php artisan swagger-lume:publish 發佈swagger相關的配置

-w406

執行該命令後,主要體現以下幾處變更

-w617

  • config/ 目錄中,添加了項目的配置文件 swagger-lume.php
  • resources/views/vendor 目錄中,生成了 swagger-lume/index.blade.php 視圖文件,用於預覽生成的API文檔

從配置文件中我們可以獲取以下關鍵信息

  • api.title 生成的API文檔顯示標題
  • routes.api 用於訪問生成的API文檔UI的路由地址默認爲 /api/documentation
  • routes.docs 用於訪問生成的API文檔原文,json格式,默認路由地址爲 /docs
  • paths.docspaths.docs_json 組合生成 api-docs.json 文件的地址,默認爲 storage/api-docs/api-docs.json,執行php artisan swagger-lume:generate命令時,將會生成該文件

語法自動提示

純手寫swagger註釋肯定是要不得的,太容易出錯,還需要不停的去翻看文檔參考語法,因此我們很有必要安裝一款能夠自動提示註釋中的註解語法的插件,我們常用的IDE是 phpstorm,在 phpstorm 中,需要安裝 PHP annotation 插件

安裝插件之後,我們在寫Swagger文檔時,就有代碼自動提示功能了

2019-01-02 13_33_59

書寫文檔

Swagger文檔中包含了很多與具體API無關的信息,我們在 app/Http/Controllers 中創建一個 SwaggerController,該控制器中我們不實現業務邏輯,只用來放置通用的文檔信息

<?php
namespace App\Http\Controllers;

use OpenApi\Annotations\Contact;
use OpenApi\Annotations\Info;
use OpenApi\Annotations\Property;
use OpenApi\Annotations\Schema;
use OpenApi\Annotations\Server;

/**
 *
 * @Info(
 *     version="1.0.0",
 *     title="演示服務",
 *     description="這是演示服務,該文檔提供了演示swagger api的功能",
 *     @Contact(
 *         email="[email protected]",
 *         name="mylxsw"
 *     )
 * )
 *
 * @Server(
 *     url="http://localhost",
 *     description="開發環境",
 * )
 *
 * @Schema(
 *     schema="ApiResponse",
 *     type="object",
 *     description="響應實體,響應結果統一使用該結構",
 *     title="響應實體",
 *     @Property(
 *         property="code",
 *         type="string",
 *         description="響應代碼"
 *     ),
 *     @Property(property="message", type="string", description="響應結果提示")
 * )
 *
 *
 * @package App\Http\Controllers
 */
class SwaggerController
{}

接下來,在業務邏輯控制器中,我們就可以寫API了


<?php
namespace App\Http\Controllers;

use App\Http\Responses\DemoAdditionalProperty;
use App\Http\Responses\DemoResp;
use Illuminate\Http\Request;
use OpenApi\Annotations\Get;
use OpenApi\Annotations\MediaType;
use OpenApi\Annotations\Property;
use OpenApi\Annotations\RequestBody;
use OpenApi\Annotations\Response;
use OpenApi\Annotations\Schema;

class ExampleController extends Controller
{

    /**
     * @Get(
     *     path="/demo",
     *     tags={"演示"},
     *     summary="演示API",
     *     @RequestBody(
     *         @MediaType(
     *             mediaType="application/json",
     *             @Schema(
     *                 required={"name", "age"},
     *                 @Property(property="name", type="string", description="姓名"),
     *                 @Property(property="age", type="integer", description="年齡"),
     *                 @Property(property="gender", type="string", description="性別")
     *             )
     *         )
     *     ),
     *     @Response(
     *         response="200",
     *         description="正常操作響應",
     *         @MediaType(
     *             mediaType="application/json",
     *             @Schema(
     *                 allOf={
     *                     @Schema(ref="#/components/schemas/ApiResponse"),
     *                     @Schema(
     *                         type="object",
     *                         @Property(property="data", ref="#/components/schemas/DemoResp")
     *                     )
     *                 }
     *             )
     *         )
     *     )
     * )
     *
     * @param Request $request
     *
     * @return DemoResp
     */
    public function example(Request $request)
    {
        // TODO 業務邏輯

        $resp         = new DemoResp();
        $resp->name   = $request->input('name');
        $resp->id     = 123;
        $resp->age    = $request->input('age');
        $resp->gender = $request->input('gender');

        $prop1        = new DemoAdditionalProperty();
        $prop1->key   = "foo";
        $prop1->value = "bar";

        $prop2        = new DemoAdditionalProperty();
        $prop2->key   = "foo2";
        $prop2->value = "bar2";

        $resp->properties = [$prop1, $prop2];

        return $resp;
    }
}

這裏,我們在響應結果中,引用了在SwaggerController中定義的 ApiResponse,還引用了一個沒有定義的ExampleResp對象,我們可以 app\Http\Responses 目錄(自己創建該目錄)中實現該ExampleResp對象,我們將響應對象都放在這個目錄中

<?php

namespace App\Http\Responses;

use OpenApi\Annotations\Items;
use OpenApi\Annotations\Property;
use OpenApi\Annotations\Schema;

/**
 * @Schema(
 *     title="demo響應內容",
 *     description="demo響應內容描述"
 * )
 *
 * @package App\Http\Responses
 */
class DemoResp extends JsonResponse
{

    /**
     * @Property(
     *     type="integer",
     *     description="ID"
     * )
     *
     * @var int
     */
    public $id = 0;

    /**
     * @Property(
     *     type="string",
     *     description="用戶名"
     * )
     *
     * @var string
     */
    public $name;

    /**
     * @Property(
     *     type="integer",
     *     description="年齡"
     * )
     *
     * @var integer
     */
    public $age;

    /**
     * @Property(
     *     type="string",
     *     description="性別"
     * )
     *
     * @var string
     */
    public $gender;

    /**
     * @Property(
     *     type="array",
     *     @Items(ref="#/components/schemas/DemoAdditionalProperty")
     * )
     *
     * @var array
     */
    public $properties = [];
}

返回對象引用其它對象


<?php
namespace App\Http\Responses;

use OpenApi\Annotations\Property;
use OpenApi\Annotations\Schema;

/**
 *
 * @Schema(
 *     title="額外屬性",
 *     description="額外屬性描述"
 * )
 *
 * @package App\Http\Responses
 */
class DemoAdditionalProperty
{
    /**
     * @Property(
     *     type="string",
     *     description="KEY"
     * )
     *
     * @var string
     */
    public $key;

    /**
     * @Property(
     *     type="string",
     *     description="VALUE"
     * )
     *
     * @var string
     */
    public $value;
}

生成文檔

執行下面的命令,就可以生成文檔了,生成的文檔在storage/api-docs/api-docs.json

php artisan swagger-lume:generate

預覽文檔

打開瀏覽器訪問 http://訪問地址/docs,可以看到如下內容

訪問 http://訪問地址/api/documentation,我們看到

接口詳細信息展開

更多

本文簡述瞭如何在Lumen項目中使用代碼註釋自動生成Swagger文檔,並配合phpstorm的代碼提示功能,然而,學會了這些還遠遠不夠,你還需要去了解Swagger文檔的語法結構,在 swagger-php 項目的 Examples 目錄中包含很多使用範例,你可以參考一下。

團隊項目中使用了swagger文檔,但是總得有個地方管理文檔吧,這裏推薦一下 Wizard 項目,該項目是一款用於團隊協作的文檔管理工具,支持Markdown文檔和Swagger文檔,感興趣的不妨嘗試一下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章