解析 API Blueprint 文件並自動化生成程式碼(可定製模板)

free46000發表於2017-06-06

最近大前端概念越來越火,本著學習的目的,寫了一個自動化解析API Blueprint文件的模板程式碼生成工具,為了提高開發效率,本工具使用nodejs開發,vue.js作為可定製化的輸出模板的輔助,本專案娛樂為主,希望能給大家提供一些思路,擴充套件下技術棧

原始碼地址

GitHub:github.com/free46000/A…

下載與使用

普通方式

  • 下載[APIBlueprintToGenerateCode]原始碼,需要注意原始碼使用ECMAScript6的語法
  • 在原始碼目錄下執行npm install命令,安裝依賴包,本過程中在會有一些安裝 .NET Framework 2.0的相關錯誤提示,可以忽略
  • 安裝完成後在原始碼目錄下執行node bin/www命令,啟動伺服器
  • 在瀏覽器位址列中輸入http://localhost:3000即可訪問頁面,頁面中可以自定義Api文件Git地址,如果Api文件沒有上傳Git,也可以把Api文件拷貝到頁面輸入框指定的路徑下,可以自動識別,點選生成按鈕,解析結果會展現在當前頁面中

注意:原始碼中是過濾了以.apib結尾的檔案列表,此處如果有需要可以聯絡作者,修改為傳遞引數控制

docker容器方式

  • 由於程式碼定製化比較強,這裡我會把DockerFile貼出來,大家有需要可以修改程式碼後自行build

效果截圖

entities效果

解析 API Blueprint 文件並自動化生成程式碼(可定製模板)
entities

apiset效果

解析 API Blueprint 文件並自動化生成程式碼(可定製模板)
apiset

主要流程

  • 通過nodegit拉取API Blueprint文件到本地(當然這一步視大家的具體情況,也可以直接把Api文件拷貝到頁面輸入框指定的路徑下)
  • 通過drafter官方解析庫解析API Blueprint文件,drafter解析後的結構並不是太友好,這裡需要寫一些適配程式碼
  • 解析Response中的json資料結構
  • 藉助vue.js生成html的模板程式碼
  • 整合到docker容器

原始碼解析

API文件git下載

API Blueprint是一套基於markdown的API描述語言規範,基於此規範可以方便的生成mock介面,這樣前端,移動端,後端可以並行開發,好處多多,希望大家也多使用。

  • nodegit地址
  • 使用Git.Clone克隆API Blueprint文件
  • 使用Repository.fetchAllfetch到最新文件
  • 根據具體情況使用Repository.mergeBranches合併分支,原始碼中是把develop分支程式碼合併到master中,程式碼邏輯在git_handler.js

解析API Blueprint

  • drafter地址
  • 使用nodefs模組,讀取檔案列表,原始碼中是過濾了下以.apib結尾的檔案列表,此處如果有需要可以聯絡作者,修改為傳遞引數控制
  • 使用drafter.parse解析API Blueprint文件,解析後的格式為
{
  "element": "parseResult",
  "content": [
    {
      "element": "category",
      "meta": {
        "classes": [
          "api"
        ],
        "title": ""
      },
      "content": [
         {
          "element": "category",
          "meta": {
            "classes": [
              "resourceGroup"
            ],
            "title": ""
          },
          "content": [

        ... ...

}複製程式碼
  • 可以發現上面的結構巢狀比較深,後面使用的時候會比較麻煩,這裡把有效資料拿到,併為每個HttpTransaction生成一個實體(JsonObject),處理邏輯在apib_parser.js中,解析之後的格式為:
[{
    href:'',//請求路徑:/get/task/{taskid}
    hrefName:'',//路徑對應name:GetTask
    title:'',//請求標題:獲取任務
    hrefVariables:[ //路徑對應Variable"content": "taskid"
        {"element": "String","content": "post_id"}
    ],
    subTitle:'',//請求標題:通過id獲取任務
    tip:'',//相關提示
    method:'',//請求型別 POST or GET ...
    response:{},//響應實體{'taskId':1,'taskName':'任務'}
    param:{}//請求引數taskId
}]複製程式碼
  • 我們可以很方便的從上面拿到請求響應的資料,正常情況下會是json格式的,例如:{'taskId':1,'taskName':'任務'},
  • 以上幾步是在nodejs的服務端完成,通訊採用ajax,取得資料後我們把HttpTransaction中請求響應的json資料轉換為對生成實體類友好的結構,處理邏輯主要在to_bean.js中,處理之後的格式為:
[{
    className: className,//實體類中名字
    fields: [{ //實體類中含有的屬性列表
        name: taskName, 
        type: String
    }],
    importTypes: [{//需要import的型別列表
        'java.util.List'
    }] 
}]複製程式碼

模板生成

  • 經過以上的準備,得到了我們需要的資料,然後藉助vue.js渲染html程式碼模板,程式碼都在bean_template.html中,目前寫了java實體類和Api介面類的模板,可自行擴充套件其他模板。下面貼出一段實體類的模板程式碼:
<div id="bean" v-if="beans">
    <div :id="bean.className" style="background: cornsilk">
        <p>package com.bean.response;</p>

        <p v-for="imp in bean.importTypes">import {{imp}};</p>

        <p>public class {{ bean.className }} {</p>
        <div v-for="field in bean.fields">
            private {{field.type}} {{field.name}};
        </div>
        <div v-for="field in bean.fields">
            public void set{{ firstToUpperCase(field.name) }}({{field.type}} {{ field.name }}) {<br>
            this.{{field.name}} = {{field.name}};<br>
            }<br><br>
            public {{field.type}} get{{ firstToUpperCase(field.name) }}() {<br>
            return this.{{field.name}};<br>
            }<br><br>
        </div>
        <p>}</p>
    </div>
</div>複製程式碼

docker整合

  • 最後整合在docker容器中,docker可以讓應用程式佈署在軟體容器下的工作可以自動化進行,不過開發接觸的偏少一些,有興趣的可以瞭解一下,下面我貼出我的DockerFile程式碼:
# 選擇image
FROM node:latest

# 建立原始碼目錄並設定當前工作路徑
RUN mkdir -p /usr/app
WORKDIR /usr/app

# 拷貝原始碼到目標路徑
COPY ./bin /usr/app/bin
COPY ./public /usr/app/public
COPY ./routes /usr/app/routes
COPY ./views /usr/app/views
COPY ./app.js /usr/app/app.js
COPY ./package.json /usr/app/package.json

RUN npm install .

CMD [ "node", "/usr/app/bin/www" ]複製程式碼

總結

目前程式碼只是在html中進行輸出,本來計劃下一步在指定目錄生成類檔案,但是有兩個問題沒有辦法很好解決,所以就暫時放棄了,一是實體類的命名;還有實體類去重,例如:任務列表和詳情介面同樣都會有任務的實體,自動化生成程式碼會生成兩個類。

本專案主要是為了熟悉NodeJS vue等前端開發知識,娛樂為主,主要寫寫實現的思路,雖然寫的比較簡陋,但是裡面用了一些比較好的開源元件API Blueprint nodegit docker 等,非常值得學習,歡迎留言交流,希望可以幫助到大家。

最後請允許打個小廣告:作者開源了一個一個優雅的實現多型別的RecyclerView類庫 支援DataBinding Form表單錄入,Github地址:github.com/free46000/M…

相關文章