巧用 Swagger 在線編輯器生成前端接口代碼

Swagger 簡要介紹

Swagger / Open API 在Restful API 領域已慢慢成爲標準,愈來愈多的系統使用swagger來規範開發接口文檔,因爲Swagger 自己並不依賴特定的語言和開發平臺,因此特別合適做爲先後端分離的接口標準來使用。 Swagger 官方提供了兩種文檔UI形式,一種是 Swagger UI, 另外一種是 Swagger Editor.node

  • Swagger UI 經常做爲項目工程的一部份,不少程序都採用自身的特性,在程序代碼上增長註釋、註解、裝飾器等方式完成swagger 的接口文檔自動生成和文檔展現。ios

  • Swagger Editor 提供了一個在線編輯的編輯器,使之能以文檔的方式編輯接口,並提供了兩塊的生成功能:服務端代碼與客戶端代碼,代碼生成涵蓋了大部分的主流語言與框架很是方便。git

直接可用的代碼

不少同窗可能有疑問,這樣生成的代碼到底能用嗎?github

個人回答不只是能用,並且很好用。 以 ng-alain 爲例typescript

代碼位置 github.com/vellengs/ty… 定製下provider 的 basePath 設置。json

export function apiConfig(): Configuration {
    return new Configuration({
        basePath: `${location.protocol}//${location.host}`
    });
}
複製代碼

註冊下模塊axios

ApiModule.forRoot(apiConfig),
複製代碼

而後把目錄釋放到 github.com/vellengs/ty… 這個目錄,看清楚,generted目錄 是能夠一字不改的,若是改了之後須要從新生成豈不是大麻煩?後端

放置到 angular 項目裏後就能夠愉快的使用 service了,以下示例: github.com/vellengs/ty…api

profileSave(event?) {
    const entry: EditProfileDto = Object.assign({}, event);
    this.coreService.userUpdate(entry).subscribe((res) => {
        if (res) {
            this.settings.setUser(res);
            this.msg.success('我的資料修改爲功');
        }
    });
}

saveSysSettings(event) {
    const entry = Object.assign({}, event);

    this.coreService.settingUpdateSettingsByName('main', entry).subscribe((res) => {
        if (res) {
            this.settingsData = res;
            this.msg.success('系統設置更新成功');
        }
    });
}

load() {
    this.coreService.settingGetSettingsByName('main').subscribe((res) => {
        if (res) {
            this.settingsData = res;
        }
    });
} 
複製代碼

方法變得能夠感知了。bash

自動生成、下載、解壓

上一步驟已經能夠使用了,可是有點小小的麻煩;每次都要打開 editor.swagger.io 粘貼文檔上去,而後去點生成,而後解壓,這樣是否是不夠平滑呢?

那讓咱們寫個腳本吧,自動完成上面的事情。 完整腳本地址

async function loadSwagger() {

    /** 讀取 swagger.json 接口文檔文件 */
    const jsonPath = path.resolve(process.cwd(), 'dist', 'swagger.json');
    const json = require(jsonPath);

    const client = axios.create({
        httpsAgent: new https.Agent({
            rejectUnauthorized: false
        })
    });

    /**
     * 提交 post 到服務器並得到下載連接
     */
    const result = await client.post(gateway, { spec: json });
    if (result.data && result.data.link) {
        const response = await client({
            method: 'GET',
            url: result.data.link,
            responseType: 'stream'
        })
        const local = path.resolve(process.cwd(), 'swagger.zip');
        const generatedFolder = path.resolve(process.cwd(), './../client/src/generated');
        const templateFolder = path.resolve(process.cwd(), 'decompress', 'typescript-angular-client');
        const decompress = path.resolve(process.cwd(), 'decompress');

        // 處理下載壓縮包文件,解壓並刪除臨時文件
        response.data.pipe(fs.createWriteStream(local)).on('finish', (done: any) => {
            fs.createReadStream(local).pipe(unzip.Extract({ path: 'decompress' })).on('close',
                async (done: any) => {
             
                    fs.unlinkSync(local); 
                    await removeFolder(generatedFolder);  
                    fs.renameSync(templateFolder, generatedFolder);
                    await removeFolder(decompress);
                });
        });
    }
}

/**
 * 若已經生成,則刪除文件夾
 * @param folder 文件夾
 */
async function removeFolder(folder: string) {
    if (fs.existsSync(folder)) {
        await new Promise((resolve) => {
            rimraf(folder, () => {
                resolve(true);
            });
        })
    }
}

loadSwagger();
複製代碼

總共沒幾行代碼,是否是以爲很簡單呢,沒錯要的就是簡單,可是很好的完成了咱們的工做。

有了腳本以後你只要

ts-node  xxxxx/apigen.ts 
複製代碼

便可完成工做。

結束語,標準的接口在先後端分離的開發中起到很好的規範做用,而平滑的開發體驗也是重要的一環,若是你有疑問,或者有更好的方式,歡迎和做者交流學習 github.com/vellengs

相關文章
相關標籤/搜索