V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
kaolalicai
V2EX  ›  Node.js

AI 考拉技术分享会--API 接口与 Typescript Interface

  •  
  •   kaolalicai · 2018-10-24 11:28:01 +08:00 · 2323 次点击
    这是一个创建于 2001 天前的主题,其中的信息可能已经有所发展或是发生改变。

    赶在祖国生日放假前,考拉 Dev team 的成员进行了小范围的技术分享会,Nick 格格分享了自己在工作中踩过的一些坑以及填坑大法。希望大家也能避开 bug,修得 node 大法!

    前言

    Interface 就是接口,在 typescript 用于类型限定。
    在 Node 项目中,我们常用 apidoc 来定义接口文档。
    那么,他们俩是否能结合起来呢?

    一、apidoc 的痛点

    apidoc Inline Documentation for RESTful web APIs,使用起来非常方便,直接在 api 上添加注释,就可以生成可视化的文档。
    但是,在实际业务中,我们有些接口比较复杂,定义返回值是一件比较痛苦的事情,如图: 微信图片编辑_20181018162237.jpg
    而且,过了一段时间之后,出于惰性,开发人员会放弃更新 API 文档,导致文档落后于实际。

    二、API Interface

    (一) API 未定义的问题

    在 js 项目中,api 返回结构一般是无法清晰地看出来的,你得跑一下接口,才知道会返回什么,或者仔细看一遍代码。这种情况下,开发人员维护 API 会面临以下问题:

    • 文档缺失:接口文档缺少对某个字段的定义,不知道该字段作何用处;
    • 字段混乱:明明是一个字段,可能在 接口 A 是叫 amount, 在接口 B 却叫 number ;
    • 重复定义:多个接口中都用到一个叫 Banner 的东西,需要在每个接口文档中定义一遍,稍有改动,需要更改多处。

    (二)使用 interface 的好处

    所以可以尝试使用 typescript 的 interface 来定义 API 的返回值结构,一个接口对应一个 interface。
    P2.png
    假设一个 api 是 product info,定义结构如下:

    /**
     * 产品明细
     */
    export interface IProductInfo {
      /**
       * 基础利息
       */
      baseRate: number
      /**
       * 加息
       */
      bonusRate: number
      /**
       * 加息提示
       */
      bonusRateStr: string
    }   
    

    另一个 api 是 product list,可以很方便地进行复用:

    /**
     * 产品列表
     */
    export interface IProductList {
      list: Array<IProductInfo>
    }
    

    这些接口定义也可以共享给前端(前端也用 typescript 的话)

    (三) apidoc + interface

    很多时候,你的痛点其实也是其他人的痛点,所以就有了开源项目,通过搜寻,我们可以找到一个 apidoc 的插件 apidoc-plugin-ts,这个插件可以根据 interface 的定义帮你生成 apidoc 需要的 @apiSuccess 内容。
    定义一个接口:

    filename: ./employers.ts
    
    export interface Employer {
      /**
       * Employer job title
       */
      jobTitle: string;
      /**
       * Employer personal details
       */
      personalDetails: {
        name: string;
        age: number;
      }
    }  
    

    引入 interface:

     @apiInterface (./employers.ts) {Person}  
    

    翻译的效果:

     @apiSuccess {String} jobTitle Job title  
     @apiSuccess {Object} personalDetails Empoyer personal details  
     @apiSuccess {String} personalDetails.name  
     @apiSuccess {Number} personalDetails.age  
    

    还支持数组结构定义呢~
    有了这个插件,就可以通过维护 interface 来维护 apidoc 了。

    三、注意

    该插件不支持匿名接口定义数组结构, 如下:

    export interface IProductList {
     list: Array<{
       a: string,
       b: string
     }>
    }
    

    AST 解析代码的时候会拿不到某些属性,会报错。

    写在最后的

    今天是属于大家的 1024 节,在今天这个值得庆祝的日子,祝大家节日快乐,向程序猿致敬,向加班 SAY NO !

    著作权归本文作者所有,未经授权,请勿转载,谢谢。

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1002 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 22:06 · PVG 06:06 · LAX 15:06 · JFK 18:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.