国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

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

Gemini / 2252人閱讀

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

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

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

swagger-decorator 的初衷是為了簡化 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ā)中也感受到,過多過度的注解反而會大大削弱代碼的可讀性,因此筆者也建議應(yīng)該在合適的時(shí)候舒心地使用
swagger-decorator,而不是本末倒置,一味地追求注解覆蓋率。swagger-decorator 已經(jīng)可以用于實(shí)體類生成與校驗(yàn)、Sequelize ORM 實(shí)體類生成、面向 Koa 的路由注解與 Swagger 文檔自動生成。我們可以使用 yarn 或者 npm 安裝 swagger-decorator 依賴,需要注意的是,因?yàn)槲覀冊陂_發(fā)中還會用到注解語法,因此還需要添加 babel-plugin-transform-decorators-legacy 插件以進(jìn)行語法兼容轉(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 即是對于實(shí)體類的注解,該注解不會改變實(shí)體類的任何屬性表現(xiàn),只是會將注解限定的屬性特性記錄在內(nèi)置的 innerEntityObject 單例中以供后用。屬性注解 entityProperty 的方法說明如下:

/**
 * 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ù)庫連接需要的參數(shù)
  primaryKey = false
}) {}

簡單的用戶實(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 {
  // 編號
  @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í)能夠迭代生成嵌套地子對象。

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

這里為了方便描述使用 Jest 測試用例說明不同的使用場景:

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

    let user = instantiate(User, {
      id: 0,
      name: "name",
      email: "a@q.com"
    });

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

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

  test("測試 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("測試嵌套實(shí)例生成", () => {
  test("測試可以遞歸生成嵌套實(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 對象模型;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 類型聲明中自動生成注解

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

// @flow

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

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

這里對應(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 文檔生成

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

封裝路由對象
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),為了避免過多的注解文檔對于代碼可讀性的干擾,筆者建議是將除了路徑與描述之外的信息放置到父類中聲明;swagger-decorator 會自動從某個(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)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/84093.html

相關(guān)文章

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

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

    printempw 評論0 收藏0
  • 2017-07-18 前端日報(bào)

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

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

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

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

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

    Vixb 評論0 收藏0
  • Spring Boot集成Swagger2

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

    liukai90 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<