前端有了這兩樣神器,不再用追着後臺要接口啦

image

DevUI是一支兼具設計視角和工程視角的團隊,服務於華爲雲 DevCloud平臺和華爲內部數箇中後臺系統,服務於設計師和前端工程師。
官方網站: devui.design
Ng組件庫: ng-devui(歡迎Star)
官方交流羣:添加DevUI小助手(微信號:devui-official)
DevUIHelper插件: DevUIHelper-LSP(歡迎Star)

前言

以前發過一個沸點,聊到前端爲了提高業務交付效率,有必要去除對上游的依賴,此次想給你們分享下我本身在去後臺依賴方面的一些實踐,歡迎你們一塊兒討論!html

image

前端依賴後臺什麼?

在整個研發鏈路上,後臺的定位是給前端提供高效、穩定的API接口,前端經過這些API去獲取須要的數據,並展現給用戶。前端

因此要去除對後臺的依賴,前端就須要本身模擬這些接口,並構造相應的測試數據。vue

怎麼模擬後臺接口?

爲了在前端模擬後臺接口,我給你們介紹第一件神器:JSON Servernode

如下是JSON Server官方對本身的定位:webpack

Get a full fake REST API with zero coding in less than 30 seconds (seriously)
無需寫代碼,在30秒內得到完整的REST API。

以我如今負責的DevCloud業務——XBoard看板項目——舉栗子,有一個接口是獲取某個看板下面的全部卡片信息(只保留關鍵字段),接口基本協議以下(接口協議提早跟後臺協商好):git

GET /v1/[projectid]/[boardid]/cards

{
  "error": null,
  "status": "success",
  "result": [
    {
      "column_id": "7c489b6746fe4329aa8c869f4c13fab5",
  "card_list": [
        {
          "id": "4634045604195569664", // 卡片ID
          "subject": "任務已ready,準備啓動開發的任務", // 卡片主題
          "sequence": "11203427", // 卡片序列號
          "index": "12", // 序號(用於拖動排序)
          "archived": false, // 是否已歸檔
          "blocked": false, // 是否設置阻塞
          "is_parent": false, // 是否父卡片
          "createdOn": "1598238210463", // 建立時間
          "updatedOn": "1598238210463", // 最近更新時間
          "parent": { // 父卡片
            "subject": "設計完成,正在進行開發的需求",
            "id": "4634045604190851072"
          },
          "board": { // 卡片所在的看板
            "id": "1661625c5f72471a81979482ab148066",
            "name": "開發"
          },
          "column": { // 狀態列
            "id": "7c489b6746fe4329aa8c869f4c13fab5",
            "name": "就緒",
            "type": "READY",
            "deleted": false
          },
          "card_type": { // 卡片類型
            "color": "#6CBFFF",
            "name": "任務",
            "icon": "icon-op-task",
            "id": "2"
          },
          "author": { // 卡片做者
            "name": "kagolzeng",
            "id": "05329882ba000f711ffec00c21191097",
            "nick_name": "kagol",
            "gender": "male"
          },
          "updater": { // 最近更新者
            "name": "kagolzeng",
            "id": "05329882ba000f711ffec00c21191097",
            "nick_name": "kagol",
            "gender": "male"
          }
        }, 
        ... // 其餘卡片
      ]
    }, 
    ... // 其餘狀態列
  ]
}

這個接口怎麼用JSON Server模擬呢?github

只須要如下4步(假設已經有項目工程,好比:NG CLI工程):web

  • 第1步:安裝JSON Server
  • 第2步:配置測試數據
  • 第3步:編寫啓動腳本命令
  • 第4步:啓動Mock服務

咱們一步一步來搭建一個Mock服務:正則表達式

第1步:安裝JSON Server

在項目根目錄下執行如下命令:npm

npm i -D json-server

第2步:配置測試數據

在項目根目錄下新建db.json文件,加上以前已經跟後臺定好的接口數據(爲避免重複,已省略部分字段):

{
  "result": [
    {
      "column_id": "7c489b6746fe4329aa8c869f4c13fab5",
  "card_list": [
        {
          "id": "4634045604195569664", // 卡片ID
          "subject": "任務已ready,準備啓動開發的任務", // 卡片主題
          "board": { // 卡片所在的看板
            "id": "1661625c5f72471a81979482ab148066",
            "name": "開發"
          },
          "column": { // 狀態列
            "id": "7c489b6746fe4329aa8c869f4c13fab5",
            "name": "就緒",
            "type": "READY",
            "deleted": false
          },
          "card_type": { // 卡片類型
            "color": "#6CBFFF",
            "name": "任務",
            "icon": "icon-op-task",
            "id": "2"
          }
        }
      ]
    }
  ]
}

第3步:編寫啓動腳本命令

只須要在package.json的scripts中編寫Mock服務的啓動腳本便可:

"mock": "node_modules/.bin/json-server --watch db.json --port 9090"

第4步:啓動Mock服務

npm run mock

啓動以後控制檯顯示:

image

在瀏覽器地址欄輸入:http://localhost:9090/cards,便可查看該接口的返回數據

image

如何構造測試數據?

你們發現以上模擬後臺接口的方式有什麼問題了沒?

測試數據的構造太麻煩!

若是每一個接口的返回數據都須要一個一個去構造,至少會有兩個問題:

  • 一是每條記錄都本身手寫,太累,數據也太死;
  • 二是想要模擬大量的數據很難,且會致使項目源文件體積變大。

爲了解決以上問題,我要給你們介紹第二件神器:Mock.js

Mock.js對本身的定位是:

生成隨機數據,攔截 Ajax 請求

Mock.js能夠生成幾乎任何你能想到的數據類型,好比數字、字符、布爾值、日期、顏色、圖片、地址、URL、名字、標題、段落等,甚至還支持正則表達式。

將Mock.js集成進來也只須要簡單的3個步驟:

  • 第1步:修改JSON Server配置
  • 第2步:修改腳本命令
  • 第3步:重啓Mock服務

第1步:修改JSON Server配置

爲了集成Mock.js,咱們須要將以前的db.json改爲db.js,並增長routes.json文件,能夠將這兩個文件放到根目錄下的mock文件夾下。

mock/db.js

var Mock = require('mockjs');

const CARDS = Mock.mock({
  "error": null,
  "status": "success",
  "result|10": [{ // 生成10個狀態列
    "column_id": "@guid",
    "card_list|20": [{ // 狀態列下有20張卡片
      "id": "@guid", // 卡片ID
      "subject": '@title', // 卡片主題
      "sequence": /d{8}/, // 卡片序列號
      "index": "@integer(1, 100)", // 序號(用於拖動排序)
      "archived": "@boolean", // 是否已歸檔
      "blocked": "@boolean", // 是否設置阻塞
      "is_parent": "@boolean", // 是否父卡片
      "createdOn": "@date", // 建立時間
      "updatedOn": "@date", // 最近更新時間
      "parent": { // 父卡片
        "id": "@guid",
        "name": "@cword(2,10)"
      },
      "board": { // 卡片所在的看板
        "id": "@guid",
        "name": "@cword(2,10)"
      },
      "column": { // 狀態列
        "id": "@guid",
        "name": "@cword(2,10)",
        "type": "@string('upper', 2, 20)",
        "deleted": "@boolean"
      },
      "card_type": { // 卡片類型
        "color": "@color",
        "name": "@cword(2,10)",
        "icon": /icon-[a-z]-{1-3}/,
        "id": "@integer(1, 100)"
      },
      "author": { // 卡片做者
        "name": "@name",
        "id": "@guid",
        "nick_name": "@name",
        "gender": "@string('lower', 4)"
      },
      "updater": { // 最近更新者
        "name": "@name",
        "id": "@guid",
        "nick_name": "@name",
        "gender": "@string('lower', 4)"
      }
    }]
  }]
});

const API = () => ({
  'cards': CARDS,
});

module.exports = API;
mock/routes.json

{
  "/cards": "/cards"
}

第2步:修改腳本命令

腳本命令也須要作相應的修改

"mock": "node_modules/.bin/json-server --watch mock/db.js --routes mock/routes.json --port 9090"

第3步:重啓Mock服務

這時咱們從新使用:

npm run mock

命令啓動Mock服務,在瀏覽器中輸入

http://localhost:9090/cards

訪問/cards接口:

image

能夠看到Mock.js爲咱們生成了很是多隨機測試數據,以前構造這些數據但是要費很大的工夫。

而且爲了構造這大量的測試數據,咱們只是在db.js中增長了不到50行代碼,不用在擔憂源文件體積太大的問題。

image

是否是很是便捷?

讓咱們一塊兒來試試業務中如何使用這些Mock接口,以及如何無縫切換成真實的後臺接口吧。

一塊兒來試試看吧

假設咱們已經用NG CLI建立了一個項目,爲了調用Mock接口,咱們須要引入Angular的HttpClientModule模塊:

src/app/app.module.ts

import { HttpClientModule } from '@angular/common/http';

imports: [
  ...,
  HttpClientModule
]

直接調用Mock服務接口

而後注入Angular的HttpClient服務,就能夠向Mock服務的/cards接口發起請求:

src/app/app.component.ts

import { HttpClient } from '@angular/common/http';

constructor(
  private http: HttpClient
) {}

ngOnInit() {
  this.http.get('http://localhost:9090/cards').subscribe(cards => {
    console.log('cards:', cards);
  });
}

獲取到的接口數據以下:

image

使用代理無縫切換後臺接口

聰明的你確定發現直接調用Mock服務的接口有問題:部署到測試環境或者現網怎麼辦?

由於環境上調用的確定是相應環境的後臺接口,而不是Mock服務的接口,因此在本地開發時將接口代理到Mock服務,實際調用接口時不加具體的域名信息。

實際調用接口應該是如下的方式:

this.http.get('/v1/cards').subscribe(cards => {
  console.log('cards:', cards);
});

爲了作到無縫切換後臺接口,即:無需修改任何代碼,本地調用Mock服務接口,線上調用後臺接口。

咱們須要在本地開發時將接口代理到Mock服務,可使用NG CLI提供代理配置proxyConfig:

angular.json

"serve": {
  "builder": "@angular-devkit/build-angular:dev-server",
  "options": {
    "browserTarget": "ng-demo:build",
    "port": 4600,
    "proxyConfig": "proxy.config.js" // 新增代理配置
  },
  ...
}

代理配置文件:

proxy.config.js

const PROXY_CONFIG = {
  '/v1': {
    target: 'http://localhost:9090/v1'
  }
};

module.exports = PROXY_CONFIG;

咱們的Mock服務不須要作任何改變。

其餘框架配置代理

若是你使用的不是NG CLI,要怎麼配置代理呢?

Vue CLI配置代理

vue.config.js

devServer: {
  proxy: {
    '/v1': {
      target: 'http://localhost:9090/v1'
    }
  }
}

Webpack配置代理

Webpack的寫法和Vue CLI的差很少

webpack.config.js

devServer: {
  proxy: {
    '/v1': {
      target: 'http://localhost:9090/v1'
    }
  }
}

CreateReactApp配置代理

React稍微麻煩一點兒,須要安裝http-proxy-middleware中間件。

const proxy = require("http-proxy-middleware");

module.exports = function(app) {
  app.use(
    proxy("/api/", {
      target: "http://localhost:9090/v1"
    })
  );
};

增長TS類型

若是你的項目使用TypeScript的話,通常都會給接口數據增長TS類型,我給你們介紹一個根據接口自動生成TS類型文件的神器:quicktype

quicktype的定位是:

Generate types and converters from JSON, Schema, and GraphQL.
從JSON、Schema和GraphQL生成類型和轉換器。

剛纔咱們已經啓動了咱們的Mock服務,在瀏覽器地址欄輸入http://localhost:9090/cards,也能夠查看/cards接口的返回數據,這時咱們可使用quicktype工具根,據接口地址生成相應的TS類型文件。

只須要2步便可:

  • 第1步:安裝quicktype
  • 第2步:生成TS類型文件

第1步:安裝quicktype

npm i -g quicktype

第2步:生成TS類型文件

quicktype http://localhost:9090/cards -o ./src/app/shared/types/card.interface.ts --runtime-typecheck

使用TS類型

import { CardInterface } from './shared/types/card.interface';

this.http.get('/v1/cards').subscribe((cards: CardInterface) => {
  console.log('cards:', cards);
});

使用TS類型有兩個顯而易見的好處:

一是類型校驗和自動提示;

二是數據文檔化和字段自動提醒和補齊。

類型校驗和自動提示:

image

數據文檔化和字段自動提醒和補齊:

image

小結

本文主要介紹如何經過JSON Server和Mock.js兩大神器,在前端搭建Mock服務,模擬後臺接口,從而在開發階段去除對後臺的依賴,提高業務交付的效率。

歡迎你們評論交流!

源碼地址:https://github.com/kagol/ng-mock-server

加入咱們

咱們是DevUI團隊,歡迎來這裏和咱們一塊兒打造優雅高效的人機設計/研發體系。招聘郵箱:muyang2@huawei.com。

文/Kagol

往期文章推薦

《RxJS源碼解析(六)——Scheduler》

《Web界面深色模式和主題化開發》

《手把手教你搭建一個灰度發佈環境》

附錄:XBoard看板項目一覽

XBoard項目的開發看板

image

相關文章
相關標籤/搜索