簡單的mock-server 解決方案

advence-liz發表於2019-04-11

這是一篇推薦一個便捷的生成mock server的命令列工具的軟文,沒錯這麼牛逼的東西就是我寫的,不過推廣效果不佳,沒有使用過json-server的小夥伴基本就把我這篇文章略過了

那掌握這個工具你能得到什麼呢?只要你安裝了node只要你會建立資料夾和檔案那麼你就可以得到一個mock server,並且這個mock server 可以簡單的擁有任意路由,這樣你就不用在自己的業務程式碼裡面mock 資料了

json-server-router已經在趣店的前端團隊使用了一段時間了,事實證明還是蠻有效果的,幹我們這行最痛苦的事情莫過於修改別人的程式碼,而做前端的很多時候可能要對別人的頁面做一些UI調整,而一個線上執行的專案業務邏輯往往很複雜,你可能連頁面都進不去更別提調整UI,也不能盲寫呀,往往造資料倆小時coding五分鐘,此時如果有完備的mock 資料上述問題將不復存在,json-server-router的資料來源就是普通的資料夾可以伴隨專案的版本控制一直存可以完美的解決上述問題

json-server-router 的作用是提供一個簡明的方式構建出擁有任意的路由的 mock server,json-server-router是對json-server的擴充套件所以要想更好的理解下面的內容一定要先了解json-serverjson-server是一個很牛逼的東西作為一個前端開發你有必要了解一下

json-server-router 要解決的問題

在使用 json-server 時你寫了如下檔案(db.json) 也就代表你得到了四個 mock 介面 /update ,/retrieve, /create ,/delete 但是實際的需求中介面路由肯定不能這麼簡單你需要的可能是 /aaa/bbb/ccc/update這樣的形式,雖然json-server可以配置rewrite可以解決部分問題,但是這並不簡單,接下來我們來看一下json-server-router的方式

// db.json
{
  "update": { "code": 200, "message": "succeed", "data": true },
  "retrieve": { "code": 200, "message": "succeed", "data": true },
  "create": { "code": 200, "message": "succeed", "data": true },
  "delete": { "code": 200, "message": "succeed", "data": true }
}
複製程式碼

json-server-router 使用方式

json-server-router 的實現理念是根據目錄結構,構建出想要的介面形式 假設我們的目標介面為 /aaa/bbb/ccc/update 那麼我們只需構件出如下的目錄結構

當遇到名稱為 index 的檔案路徑拼接的時候會忽略index,當遇見鍵值為 index路徑拼接同樣也會忽略index

- aaa
  - bbb
    + ccc.json   // 在ccc.json中新增 update
or 

- aaa
  - bbb
    - ccc
      +index.json // 在index.json中新增update

複製程式碼

路由生成示意大概下面這個樣子,mock為 mock 檔案的根目錄

mock/books/index.json
-mock
 + index.json    ------>   /xxx
 + book.json     ------>   /book/xxx
 - foo
   + index.json  ------>  /foo/xxx
   + bar.json    ------>  /foo/bar/xxx
複製程式碼

假設/books/index.json內容如下

將對應生成四個介面 /books/ /books/retrieve /books/create /books/delete

{
  "index": { "code": 200, "message": "succeed", "data": true }, // /books/
  "retrieve": { "code": 200, "message": "succeed", "data": true },// /books/retrieve
  "create": { "code": 200, "message": "succeed", "data": true },// /books/create
  "delete": { "code": 200, "message": "succeed", "data": true }// /books/delete
}
複製程式碼

安裝&使用

當前全域性安裝之後你會得到一個叫jsr的全域性命令,根據前面的介紹這時候其實你只需構件出一個包含mock files 的根目錄就足夠了

$ npm install json-server-router -g
$ jsr --root mock
複製程式碼

命令引數

jsr [options]

Options Required:
  --root, -r  Paths to mock files parent dir          [string] [required]

Options:
  --config           Path to JSON config file  [string] [default:jsr.config.js]
  --port, -p         Set port                    [number] [default: 3000]
  --host                                [string] [default: "local ip"]
  --static           Set static files directory(same as json-server) [string] [default: "public"]
  --watch, -w        Watch file(s)             [boolean] [default: false]
  --open, -o         open                      [boolean] [default: false]
  --middlewares, -m  Paths to middleware files TODO               [array]
  --help, -h         Show help                                  [boolean]
  --version, -v      Show version number                        [boolean]

Examples:
  jsr --root mock
  jsr --root mock --port 3000
複製程式碼

引數說明

  • config 設定配置檔案預設配置檔案的地址是當前目錄的下的jsr.config.js
  • static 靜態資源的地址跟json-server是一致的,需要注意的是如果 static路徑存在的話json-server-router會自動建立一個包含所有路由的index.html,如果static目錄不存在,不會自動建立目錄生成index.html
  • watch 監控檔案變化自動重新載入

jsr.config.js simple

module.exports = {
  root: 'mock',
  port: 3000,
}
複製程式碼

GET

json-server-router其底層依賴json-server所構建,所以在不出意外的情況下同時也擁有json-server的所有GET請求相關功能

當使用json-server 我們可以通過構建路由/get/users?_page=7&_limit=10進行分頁查詢但是query的關鍵詞必須是指定的 在json-server-router中可以再jsr.config.js中自定義queryMap欄位來修改關鍵詞的名字,配置好了之後就可以通過/get/users?page=7&len=10進行分頁查詢

//jsr.config.js
{
  queryMap: [['_page', 'page'], ['_limit', 'len']]

}
複製程式碼

POST PUT DELETE

關於非GET請求你不需要定義mock filesjson-server-router對所有非GET請求進行統一處理不管其路由是什麼一致通過handler函式處理

返回結果如下

{
    "body": {},
    "code": 200,
    "ip": "::1",
    "message": "succeed",
    "url": "/books/"
}
複製程式碼

你可以通過重寫jsr.config.js中的handler 函式自定義其處理結果

//jsr.config.js
 {
 /**
   * 處理所有非GET請求
   * 當query fial 有值的時候認為請求設定為失敗狀態
   */
  handler (req, res, next) {
    const { ip, originalUrl, body } = req
    const isFail = !!req.query.fail
    res.json({
      code: isFail ? 500 : 200,
      message: isFail ? 'failed' : 'succeed',
      cookie: req.get('cookie'),
      ip,
      url: originalUrl,
      body: body
    })
  }
 }
複製程式碼

但是有的時候你可以能需要非GET請求得到跟GET請求一樣的行為

為了完成將非GET請求跟GET一致的行為,對 mock 資料新增了配置 "list[get]"生成的路由不會包含[get] 當用POST 訪問 /xxxx/list時就會得到mock檔案中定義的資料

{
  "list[get]": [
    { "id": 0, "name": "book1" },
    { "id": 1, "name": "book2" },
    { "id": 2, "name": "book3" }
  ]
}

複製程式碼

tips

  • jsr執行起來之後在命令視窗鍵入rs會重新載入

  • static路徑存在的時候,路由/jsr 會返回所有路由資訊,當static路徑不存在的時候路由/會返回所有路由資訊

相關文章