简单的mock-server 解决方案

1,396 阅读5分钟

这是一篇推荐一个便捷的生成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路径不存在的时候路由/会返回所有路由信息