API Multi Version - 相同Eedpoint (不採用)

  • 在整個Model定義路由規則

  • "http": {
        "path": ":apiVersion/Groups"
      },
    
  • 在API 介面帶入version
  • Group.remoteMethod('listAllGroups', {
        http: { path: '/', verb: 'get' },
        accepts: [
          {
            arg: 'version', type: 'object', description: 'API version eg. v1, v2, etc.',
            http: function (context) {
              return { apiVersion: context.req.apiVersion || 'v1.0' };
            }
          },
          { arg: 'req', type: 'object', 'http': { source: 'req' } },
          { arg: 'groupId', type: 'string', required: false, description: 'groupId' },
          { arg: 'name', type: 'string', description: 'name of group' },
          { arg: 'count', type: 'number', default: 1000, description: 'Data retrived. limit: 1000' },
          { arg: 'index', type: 'number', default: 1, description: 'Starting Index' },
          { arg: 'sortby', type: 'string', description: 'Sort by the specified property' },
          { arg: 'desc', type: 'boolean', default: false, description: 'order by desc or not' }],
        returns: { arg: 'data', type: 'GroupList', root: true },
        description: 'List/find groups'
      });
    
  • remote method function會像這樣
  •  Group.listAllGroups = async (version, req, groupId = null, name = null, count = 1000, index = 1, sortby = 'name', desc = false, cb) => {
        switch (version.apiVersion) {
          case 'v1':
            // version specific API method
            break;
          case 'v2':
            // version specific API method
            break;
          default:
            cb(null, false);
        }
    
  • 缺點

    • 當API兩版本的介面(要傳的參數)有差異時,此方法就不能用了
    • 因為API的驗證是用loopback model validate,如果版本間對於某個model的定義不同,那勢必要拆檔案,這樣一來此方法也不能用了

      • ex. 以POST /Groups 為例(新建Groups),POST Request body會轉成GroupCreateInstance

        Group.remoteMethod('createGroup', {
            http: { path: '/', verb: 'post' },
            accepts: [
              { arg: 'req', type: 'object', 'http': { source: 'req' } },
              { arg: 'data', type: 'GroupCreateInstance', http: { source: 'body' }, required: true, description: 'name: name of group. description: group description. type: 1(email), 2(line). config.host: host of smtp server. config.port: port of smtp server. config.secure: smtp secure transport. config.method: TLS or SSL, required when config.secure is true. config.username: smtp username. config.password: smtp password. config.senderEmail: smtp MAIL FROM. config.emailSubject: subject of email. sendList[{firstName}] (option): firstName of send target. sendList[{lastName}] (option): lastName of send target. sendList[{target}]: email address or line token, based on the type.' }
            ],
            returns: { arg: 'data', type: 'object', root: true },
            description: 'Create new group'
          });
        
        {
          "name": "GroupCreateInstance",
          "base": "Model",
          "strict": true,
          "properties": {
            "name": {
              "type": "string",
              "required": true
            },
            "description": {
              "type": "string",
              "required": false
            },
            "type": {
              "type": "number",
              "required": true
            },
            "config": {
              "type": "GroupConfigInstance"
            },
            "sendList": {
              "type": [
                "GroupSendObject"
              ]
            }
          },
          "validations": [],
          "relations": {},
          "acls": [],
          "methods": {}
        }
        
      • 但假設在下一個版本時,GroupCreateInstance裡的name改成groupName, 這樣的話就需要新增一個GroupCreateInstanceV2的model(json檔),而且remoteMethod的路由定義也不能用同一個了,因為該定義需要指定reqeust body會轉成那一種model

    • 假設兩版本間的API介面、用到的model都一樣,但api裡用到不同的node module,這樣一來專案就會越來越肥, dependency越來越多

  • 優點

    • 架構較為乾淨

    • api endpoint不用分別建立

  • 適用情境

    • api版本間的介面/用到的model/相依套件都一樣時,僅流程/邏輯上微幅修改時,就適用此做法

results matching ""

    No results matching ""