背景
之前做專案都沒有用到mock
服務,都是等後端給介面欄位或者前端留空位;但新公司的專案需要搭建mock
服務,本想把舊專案的json-server
搬過來就好了,不過發現新增一個 mock api 步驟過於繁複,mock
服務本應簡單為主,所以決定自己寫一個(本以為寫個 json 檔案就好了…)。
預期設計
按照我對mock
服務的理解,只需檢測 restful 風格的 url 返回對應資料就好了,然後簡單看了下文件示例
1、建立db.json
{
"posts": [
{ "id": 1, "title": "json-server", "author": "typicode" }
],
"comments": [
{ "id": 1, "body": "some comment", "postId": 1 }
],
"profile": { "name": "typicode" }
}
複製程式碼
2、啟動
$ json-server –watch db.json
3、訪問http://localhost:3000/posts/1
{ "id": 1, "title": "json-server", "author": "typicode" }
複製程式碼
哇這不是很簡單嗎(為自己埋坑),接下來只要將資料改造成路由的形式
// db.js
module.expors = {
`/posts`: require(`./data/posts.json`),
`/user/login`: require(`./data/user/login.json`),
`/user/logout`: require(`./data/user/logout.json`)
}
複製程式碼
目錄結構
mock
|
└───data
| |
| └───posts.json
| └───user
| |
| └───login.json
| └───logout.json
|
└───db.js
└───server.js // 預期通過 node server.js 執行
複製程式碼
實踐一
編寫 server.js
const jsonServer = require(`json-server`)
const server = jsonServer.create()
const middlewares = jsonServer.defaults()
// Set default middlewares (logger, static, cors and no-cache)
server.use(middlewares)
// 獲取db資料
const db = require(`./db.js`)
// Use router
server.use(jsonServer.router(db))
server.listen(3000, () => {
console.log(`JSON Server is running on 3000`)
})
複製程式碼
執行 node server.js 後報錯
/ aren`t supported, if you want to tweak default routes, see
https://github.com/typicode/json-server/#add-custom-routes
複製程式碼
看來是不支援路由風格的db
資料,那嘗試將db
資料改成物件巢狀的模式,雖然這不夠直觀看出介面地址,但好歹也只是一個 json 檔案
// db.js
module.expors = {
`posts`: require(`./data/posts.json`),
`user`: {
`login`: require(`./data/user/login.json`),
`logout`: require(`./data/user/logout.json`)
}
}
複製程式碼
這下可以執行了,開啟http://localhost:3000/user/login
,誒怎麼是空物件{}
,日誌顯示GET /user/login 404 4.161 ms - 2
;開啟http://localhost:3000/user
,能夠顯示 login 和 logout 的資料,看來是當成/user
介面了,那 json-server 怎麼返回/user/login
的資料? 不支援路由風格就算了,連這個也不能讀取…
實踐二
看到有個jsonServer.rewriter
方法,我們可以再次改寫db.js
和server.js
// db.js
module.expors = {
`posts`: require(`./data/posts.json`),
`user_login`: require(`./data/user/login.json`),
`user_logout`: require(`./data/user/logout.json`)
}
複製程式碼
// server.js
... 省略部分程式碼
// 需要加在 server.use(router) 前
server.use(jsonServer.rewriter({
`/user/login`: `/user_login`,
`/user/logout`: `/user_logout`
}))
// Use router
server.use(jsonServer.router(db))
server.listen(3000, () => {
console.log(`JSON Server is running on 3000`)
})
複製程式碼
這樣終於是可以正常執行mock
服務了,雖然這有點醜,而且 json-server 本身只支援/posts/:id
(根據 item 的指定 id 屬性選取),不支援/posts/:id/xxx
這種寫法(需要手動新增jsonServer.rewriter
)
完善
當檔案越來越多的時候,手動新增db.js
和jsonServer.rewriter
是一種麻煩,所以需要自動根據檔案目錄生成db
和jsonServer.rewriter
,這樣我們新增 api 只需在合適的路徑新增 json 檔案(程式碼最後會附上地址)
疑惑
作為前端使用的mock
服務,其實只需解決開發時獲取 get 請求資料的空白,避免先在頁面填充資料導致聯調時需要修改;再一個就是編寫足夠直觀、足夠簡單,在這一點上私以為 json-server 沒有做得很好(希望是我沒有領悟到 json-server 的使用方法),不能直觀的看出路由介面,不能很好的體現 restful api(需要新增jsonServer.rewriter
)。
如果是我編寫一個mock
服務的話,我可能會採用koa
和koa-router
,只需編寫 get 路由介面
// router.js
router.get(`/posts`, () => require(`./data/posts.json`))
router.get(`/posts/:id`, () => require(`./data/posts/id.json`))
router.get(`/user/login`, () => require(`./data/user/login.json`))
router.get(`/user/logout`, () => require(`./data/user/logout.json`))
複製程式碼
ps:我知道 json-server 也有server.get
方法,但這這樣似乎與db.json
檔案衝突了
我會每一個介面都寫一個 json 檔案,這樣至少看起來很直觀,寫起來也足夠簡單,而且我手動實現 restful 比 json-server 不完全支援清晰很多;
總結
第一次實踐搭建 json-server,可能用法和理解上不太對,希望有問題可以指出;我把mock
服務封裝到自己的 vue-cli template 上了,可以通過vue init masongzhi/vue-template-webpack my-project
安裝,mock
服務在/mock
資料夾下。