成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JavaScript 中基于 swagger-decorator 的自動(dòng)實(shí)體類構(gòu)建與 Swagger

Gemini / 2301人閱讀

摘要:中基于的自動(dòng)實(shí)體類構(gòu)建與接口文檔生成是筆者對(duì)于開源項(xiàng)目的描述,對(duì)于不反感使用注解的項(xiàng)目中利用添加合適的實(shí)體類或者接口類注解,從而實(shí)現(xiàn)支持嵌套地實(shí)體類校驗(yàn)與生成等模型生成基于的接口文檔生成等等功能。

JavaScript 中基于 swagger-decorator 的自動(dòng)實(shí)體類構(gòu)建與 Swagger 接口文檔生成是筆者對(duì)于開源項(xiàng)目 swagger-decorator 的描述,對(duì)于不反感使用注解的項(xiàng)目中利用 swagger-decorator 添加合適的實(shí)體類或者接口類注解,從而實(shí)現(xiàn)支持嵌套地實(shí)體類校驗(yàn)與生成、Sequelize 等 ORM 模型生成、基于 Swagger 的接口文檔生成等等功能。如果有對(duì) JavaScript 語(yǔ)法使用尚存不明的可以參考 JavaScript 學(xué)習(xí)與實(shí)踐資料索引或者現(xiàn)代 JavaScript 開發(fā):語(yǔ)法基礎(chǔ)與實(shí)踐技巧系列文章。

swagger-decorator: 一處注解,多處使用

swagger-decorator 的初衷是為了簡(jiǎn)化 JavaScript 應(yīng)用開發(fā),筆者在編寫 JavaScript 應(yīng)用(Web 前端 & Node.js)時(shí)發(fā)現(xiàn)我們經(jīng)常需要重復(fù)地創(chuàng)建實(shí)體類、添加注釋或者進(jìn)行類型校驗(yàn),swagger-decorator 希望能夠讓開發(fā)者一處注解、多處使用。需要強(qiáng)調(diào)的是,在筆者多年的 Java 應(yīng)用開發(fā)中也感受到,過(guò)多過(guò)度的注解反而會(huì)大大削弱代碼的可讀性,因此筆者也建議應(yīng)該在合適的時(shí)候舒心地使用
swagger-decorator,而不是本末倒置,一味地追求注解覆蓋率。swagger-decorator 已經(jīng)可以用于實(shí)體類生成與校驗(yàn)、Sequelize ORM 實(shí)體類生成、面向 Koa 的路由注解與 Swagger 文檔自動(dòng)生成。我們可以使用 yarn 或者 npm 安裝 swagger-decorator 依賴,需要注意的是,因?yàn)槲覀冊(cè)陂_發(fā)中還會(huì)用到注解語(yǔ)法,因此還需要添加 babel-plugin-transform-decorators-legacy 插件以進(jìn)行語(yǔ)法兼容轉(zhuǎn)化。

# 使用 npm 安裝依賴

$ npm install swagger-decorator -S

$

# 使用 yarn 安裝依賴

$ yarn add swagger-decorator

$ yarn add babel-plugin-transform-decorators-legacy -D

# 導(dǎo)入需要的工具函數(shù)
import { 
    wrappingKoaRouter,
    entityProperty,
    ...
} from "swagger-decorator";
實(shí)體類注解

swagger-decorator 的核心 API 即是對(duì)于實(shí)體類的注解,該注解不會(huì)改變實(shí)體類的任何屬性表現(xiàn),只是會(huì)將注解限定的屬性特性記錄在內(nèi)置的 innerEntityObject 單例中以供后用。屬性注解 entityProperty 的方法說(shuō)明如下:

/**
 * Description 創(chuàng)建某個(gè)屬性的描述
 * @param type 基礎(chǔ)類型 self - 表示為自身
 * @param description 描述
 * @param required 是否為必要參數(shù)
 * @param defaultValue 默認(rèn)值
 * @param pattern
 * @param primaryKey 是否為主鍵
 * @returns {Function}
 */
export function entityProperty({
  // 生成接口文檔需要的參數(shù)
  type = "string",
  description = "",
  required = false,
  defaultValue = undefined,

  // 進(jìn)行校驗(yàn)所需要的參數(shù)
  pattern = undefined,

  // 進(jìn)行數(shù)據(jù)庫(kù)連接需要的參數(shù)
  primaryKey = false
}) {}

簡(jiǎn)單的用戶實(shí)體類注解如下,這里的數(shù)據(jù)類型 type 支持 Swagger 默認(rèn)的字符格式的類型描述,也支持直接使用 JavaScript 類名或者 JavaScript 數(shù)組。

// @flow

import { entityProperty } from "../../src/entity/decorator";
import UserProperty from "./UserProperty";
/**
 * Description 用戶實(shí)體類
 */
export default class User {
  // 編號(hào)
  @entityProperty({
    type: "integer",
    description: "user id, auto-generated",
    required: true
  })
  id: string = 0;

  // 姓名
  @entityProperty({
    type: "string",
    description: "user name, 3~12 characters",
    required: false
  })
  name: string = "name";

  // 郵箱
  @entityProperty({
    type: "string",
    description: "user email",
    pattern: "email",
    required: false
  })
  email: string = "email";

  // 屬性
  @entityProperty({
    type: UserProperty,
    description: "user property",
    required: false
  })
  property: UserProperty = new UserProperty();
}

export default class UserProperty {
  // 朋友列表
  @entityProperty({
    type: ["number"],
    description: "user friends, which is user ids",
    required: false
  })
  friends: [number];
}

Swagger 內(nèi)置數(shù)據(jù)類型定義:

Common Name type format Comments
integer integer int32 signed 32 bits
long integer int64 signed 64 bits
float number float
double number double
string string
byte string byte base64 encoded characters
binary string binary any sequence of octets
boolean boolean
date string date As defined by full-date - RFC3339
dateTime string date-time As defined by date-time - RFC3339
password string password Used to hint UIs the input needs to be obscured.
實(shí)例生成與校驗(yàn)

實(shí)體類定義完畢之后,我們首先可以使用 instantiate 函數(shù)為實(shí)體類生成實(shí)例;不同于直接使用 new 關(guān)鍵字創(chuàng)建,instantiate 能夠根據(jù)指定屬性的數(shù)據(jù)類型或者格式進(jìn)行校驗(yàn),同時(shí)能夠迭代生成嵌套地子對(duì)象。

/**
 * Description 從實(shí)體類中生成對(duì)象,并且進(jìn)行數(shù)據(jù)校驗(yàn);注意,這里會(huì)進(jìn)行遞歸生成,即對(duì)實(shí)體類對(duì)象同樣進(jìn)行生成
 * @param EntityClass 實(shí)體類
 * @param data 數(shù)據(jù)對(duì)象
 * @param ignore 是否忽略校驗(yàn)
 * @param strict 是否忽略非預(yù)定義類屬性
 * @throws 當(dāng)校驗(yàn)失敗,會(huì)拋出異常
 */
export function instantiate(
  EntityClass: Function,
  data: {
    [string]: any
  },
  { ignore = false, strict = true }: { ignore: boolean, strict: boolean } = {}
): Object {}

這里為了方便描述使用 Jest 測(cè)試用例說(shuō)明不同的使用場(chǎng)景:

describe("測(cè)試實(shí)體類實(shí)例化函數(shù)", () => {
  test("測(cè)試 User 類實(shí)例化校驗(yàn)", () => {
    expect(() => {
      instantiate(User, {
        name: "name"
      }).toThrowError(/validate fail!/);
    });

    let user = instantiate(User, {
      id: 0,
      name: "name",
      email: "[email protected]"
    });

    // 判斷是否為 User 實(shí)例
    expect(user).toBeInstanceOf(User);
  });

  test("測(cè)試 ignore 參數(shù)可以允許忽略校驗(yàn)", () => {
    instantiate(
      User,
      {
        name: "name"
      },
      {
        ignore: true
      }
    );
  });

  test("測(cè)試 strict 參數(shù)可以控制是否忽略額外參數(shù)", () => {
    let user = instantiate(
      User,
      {
        name: "name",
        external: "external"
      },
      {
        ignore: true,
        strict: true
      }
    );

    expect(user).not.toHaveProperty("external", "external");

    user = instantiate(
      User,
      {
        name: "name",
        external: "external"
      },
      {
        ignore: true,
        strict: false
      }
    );

    expect(user).toHaveProperty("external", "external");
  });
});

describe("測(cè)試嵌套實(shí)例生成", () => {
  test("測(cè)試可以遞歸生成嵌套實(shí)體類", () => {
    let user = instantiate(User, {
      id: 0,
      property: {
        friends: [0]
      }
    });

    expect(user.property).toBeInstanceOf(UserProperty);
  });
});
Sequelize 模型生成

Sequelize 是 Node.js 應(yīng)用中常用的 ORM 框架,swagger-decorator 提供了 generateSequelizeModel 函數(shù)以方便從實(shí)體類中利用現(xiàn)有的信息生成 Sequelize 對(duì)象模型;generateSequelizeModel 的第一個(gè)參數(shù)輸入實(shí)體類,第二個(gè)參數(shù)輸入需要覆寫的模型屬性,第三個(gè)參數(shù)設(shè)置額外屬性,譬如是否需要將駝峰命名轉(zhuǎn)化為下劃線命名等等。

const originUserSequelizeModel = generateSequelizeModel(
  User,
  {
    _id: {
      primaryKey: true
    }
  },
  {
    mappingCamelCaseToUnderScore: true
  }
);

const UserSequelizeModel = sequelize.define(
  "b_user",
  originUserSequelizeModel,
  {
    timestamps: false,
    underscored: true,
    freezeTableName: true
  }
);

UserSequelizeModel.findAll({
  attributes: { exclude: [] }
}).then(users => {
  console.log(users);
});
從 Flow 類型聲明中自動(dòng)生成注解

筆者習(xí)慣使用 Flow 作為 JavaScript 的靜態(tài)類型檢測(cè)工具,因此筆者添加了 flowToDecorator 函數(shù)以自動(dòng)地從 Flow 聲明的類文件中提取出類型信息;內(nèi)部原理參考現(xiàn)代 JavaScript 開發(fā):語(yǔ)法基礎(chǔ)與實(shí)踐技巧 一書中的 JavaScript 語(yǔ)法樹與代碼轉(zhuǎn)化章節(jié)。該函數(shù)的使用方式為:

// @flow

import { flowToDecorator } from "../../../../src/transform/entity/flow/flow";

test("測(cè)試從 Flow 中提取出數(shù)據(jù)類型并且轉(zhuǎn)化為 Swagger 接口類", () => {
  flowToDecorator("./TestEntity.js", "./TestEntity.transformed.js").then(
    codeStr => {
      console.log(codeStr);
    },
    err => {
      console.error(err);
    }
  );
});

這里對(duì)應(yīng)的 TestEntity 為:

// @flow

import AnotherEntity from "./AnotherEntity";

class Entity {
  // Comment
  stringProperty: string = 0;

  classProperty: Entity = null;

  rawProperty;

  @entityProperty({
    type: "string",
    description: "this is property description",
    required: true
  })
  decoratedProperty;
}

轉(zhuǎn)化后的實(shí)體類為:

// @flow

import { entityProperty } from "swagger-decorator";

import AnotherEntity from "./AnotherEntity";

class Entity {
  // Comment
  @entityProperty({
    type: "string",
    required: false,
    description: "Comment"
  })
  stringProperty: string = 0;

  @entityProperty({
    type: Entity,
    required: false
  })
  classProperty: Entity = null;

  @entityProperty({
    type: "string",
    required: false
  })
  rawProperty;

  @entityProperty({
    type: "string",
    description: "this is property description",
    required: true
  })
  decoratedProperty;
}
接口注解與 Swagger 文檔生成

對(duì)于 Swagger 文檔規(guī)范可以參考 OpenAPI Specification ,而對(duì)于 swagger-decorator 的實(shí)際使用可以參考本項(xiàng)目的使用示例或者 基于 Koa2 的 Node.js 應(yīng)用模板 。

封裝路由對(duì)象
import { wrappingKoaRouter } from "swagger-decorator";

...

const Router = require("koa-router");

const router = new Router();

wrappingKoaRouter(router, "localhost:8080", "/api", {
  title: "Node Server Boilerplate",
  version: "0.0.1",
  description: "Koa2, koa-router,Webpack"
});

// define default route
router.get("/", async function(ctx, next) {
  ctx.body = { msg: "Node Server Boilerplate" };
});

// use scan to auto add method in class
router.scan(UserController);
定義接口類
export default class UserController extends UserControllerDoc {
  @apiRequestMapping("get", "/users")
  @apiDescription("get all users list")
  static async getUsers(ctx, next): [User] {
    ctx.body = [new User()];
  }

  @apiRequestMapping("get", "/user/:id")
  @apiDescription("get user object by id, only access self or friends")
  static async getUserByID(ctx, next): User {
    ctx.body = new User();
  }

  @apiRequestMapping("post", "/user")
  @apiDescription("create new user")
  static async postUser(): number {
    ctx.body = {
      statusCode: 200
    };
  }
}

在 UserController 中是負(fù)責(zé)具體的業(yè)務(wù)實(shí)現(xiàn),為了避免過(guò)多的注解文檔對(duì)于代碼可讀性的干擾,筆者建議是將除了路徑與描述之外的信息放置到父類中聲明;swagger-decorator 會(huì)自動(dòng)從某個(gè)接口類的直接父類中提取出同名方法的描述文檔。

export default class UserControllerDoc {
  @apiResponse(200, "get users successfully", [User])
  static async getUsers(ctx, next): [User] {}

  @pathParameter({
    name: "id",
    description: "user id",
    type: "integer",
    defaultValue: 1
  })
  @queryParameter({
    name: "tags",
    description: "user tags, for filtering users",
    required: false,
    type: "array",
    items: ["string"]
  })
  @apiResponse(200, "get user successfully", User)
  static async getUserByID(ctx, next): User {}

  @bodyParameter({
    name: "user",
    description: "the new user object, must include user name",
    required: true,
    schema: User
  })
  @apiResponse(200, "create new user successfully", {
    statusCode: 200
  })
  static async postUser(): number {}
}
運(yùn)行應(yīng)用

run your application and open swagger docs (PS. swagger-decorator contains Swagger UI):

/swagger

/swagger/api.json

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/84093.html

相關(guān)文章

  • swagger-decorator:注解方式為 Koa2 應(yīng)用自動(dòng)生成 Swagger 文檔

    摘要:注解方式為應(yīng)用動(dòng)態(tài)生成文檔目前我司服務(wù)端應(yīng)用程序框架主要采用了與,而因?yàn)榻衲暧泻芏嗟恼{(diào)研階段的產(chǎn)品線發(fā)布,持續(xù)部署接口文檔以及線上質(zhì)量監(jiān)控這三個(gè)問題愈發(fā)突出。 swagger-decorator:注解方式為 Koa2 應(yīng)用自動(dòng)生成 Swagger 文檔 從屬于筆者的服務(wù)端應(yīng)用程序開發(fā)與系統(tǒng)架構(gòu),記述了如何在以 Koa2 與 koa-router 開發(fā)服務(wù)端應(yīng)用時(shí),通過(guò)自定義 swagg...

    printempw 評(píng)論0 收藏0
  • 2017-07-18 前端日?qǐng)?bào)

    摘要:前端日?qǐng)?bào)精選常用實(shí)例的實(shí)現(xiàn)與封裝實(shí)現(xiàn)一個(gè)構(gòu)建基于的可擴(kuò)展應(yīng)用規(guī)范翻譯從到中文開源中國(guó)兩級(jí)緩存實(shí)踐掘金中基于的自動(dòng)實(shí)體類構(gòu)建與接口文檔生成某熊的全棧之路繼承總結(jié)教程中的五種組件形式掘金再說(shuō)的問題前端開發(fā)前端每周清單第期正式 2017-07-18 前端日?qǐng)?bào) 精選 javascript常用實(shí)例的實(shí)現(xiàn)與封裝實(shí)現(xiàn)一個(gè) SwiperRekit 2.0 構(gòu)建基于React+Redux+React-r...

    lauren_liuling 評(píng)論0 收藏0
  • 前端每周清單半年盤點(diǎn)之 Node.js 篇

    摘要:前端每周清單專注前端領(lǐng)域內(nèi)容,以對(duì)外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn)分為新聞熱點(diǎn)開發(fā)教程工程實(shí)踐深度閱讀開源項(xiàng)目巔峰人生等欄目。對(duì)該漏洞的綜合評(píng)級(jí)為高危。目前,相關(guān)利用方式已經(jīng)在互聯(lián)網(wǎng)上公開,近期出現(xiàn)攻擊嘗試爆發(fā)的可能。 前端每周清單專注前端領(lǐng)域內(nèi)容,以對(duì)外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn);分為新聞熱點(diǎn)、開發(fā)教程、工程實(shí)踐、深度閱讀、開源項(xiàng)目、巔峰人生等欄目。歡...

    kid143 評(píng)論0 收藏0
  • 前端每周清單半年盤點(diǎn)之 JavaScript

    摘要:前端每周清單專注前端領(lǐng)域內(nèi)容,以對(duì)外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn)分為新聞熱點(diǎn)開發(fā)教程工程實(shí)踐深度閱讀開源項(xiàng)目巔峰人生等欄目。背后的故事本文是對(duì)于年之間世界發(fā)生的大事件的詳細(xì)介紹,闡述了從提出到角力到流產(chǎn)的前世今生。 前端每周清單專注前端領(lǐng)域內(nèi)容,以對(duì)外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn);分為新聞熱點(diǎn)、開發(fā)教程、工程實(shí)踐、深度閱讀、開源項(xiàng)目、巔峰人生等欄目。歡迎...

    Vixb 評(píng)論0 收藏0
  • Spring Boot集成Swagger2

    摘要:前言目前互聯(lián)網(wǎng)開發(fā)市場(chǎng)都流行前后臺(tái)真正的分離,后臺(tái)提供數(shù)據(jù)接口,前臺(tái)負(fù)責(zé)請(qǐng)求數(shù)據(jù)并渲染。今天就介紹一款將接口文檔編寫和測(cè)試合并一起的集大成者,也是目前很多企業(yè)再用的一個(gè)管理工具。 前言:目前互聯(lián)網(wǎng)開發(fā)市場(chǎng)都流行前后臺(tái)真正的分離,后臺(tái)提供數(shù)據(jù)API接口,前臺(tái)負(fù)責(zé)請(qǐng)求數(shù)據(jù)并渲染。那么我們程序猿們?cè)诰帉懡涌诘臅r(shí)候,最不方便之處就是寫完接口后需要進(jìn)行文檔的編寫以及接口的測(cè)試。今天就介紹一款將接...

    liukai90 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<