Giter Site home page Giter Site logo

yy7054wyq5 / simple-mock Goto Github PK

View Code? Open in Web Editor NEW

This project forked from keyzf/simple-mock

0.0 2.0 0.0 60 KB

以注入到 node server 的 API 代理方式,实现简洁而功能强大的 API MOCK 功能,支持自动保存后端 API 数据到本地

License: MIT License

JavaScript 85.37% Batchfile 0.23% HTML 8.61% CSS 5.78%

simple-mock's Introduction

SIMPLE-MOCK

NPM version npm download

以注入到 node server 的 API 代理方式,实现简洁而功能强大的 API MOCK 功能。附带自动保存真实 API 接口返回数据功能。

SIMPLE-MOCK 的特色

  • 不侵入浏览器端代码:node server 注入模式实现 MOCK,不影响浏览器端编码
  • MOCK 实现简单:可自动保存后端 API 返回内容,mock 数据编写无需繁琐流程
  • 自定义 MCOK 方式简单强大:commonjs 方式的自定义 MOCK 数据自定义编写,无学习门槛,简洁而强大,能实现各种自定义逻辑
  • 不受后端各种问题牵制:API 不可用时替代,不阻塞前端开发
  • 提升开发体验:API 请求多、慢,MOCK 情况下,开发调试体验更好
  • 方便重现各种场景:简洁而强大的自定义 MOCK 规则编写,能快速重现各种数据场景,重现测试反馈问题 so easy
  • more...

安装与使用

安装

yarn add -d @lzwme/simple-mock

使用

在 nodejs 服务中的 API 代理部分,加入 saveApi 相关逻辑。

这里以 http-proxy 作为代理示例,具体参见 server/app.js 中的源码。示例参考:

const app = require('express')();
const bodyParser = require('body-parser');
const httpProxy = require('http-proxy');
const apiProxy = httpProxy.createProxyServer();
const queryString = require('querystring');

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

/**
 * 接口代理配置与mock
 */
const apiMock = require('@lzwme/simple-mock');

app.all('/{api,rest}/**', async function(req, res) {
  // 开发模式下且可 mock 的情况
  if (appConfig.media === 'dev' && await apiMock.render(req, res)) {
    return;
  }

  console.log('[apiProxy]', req._parsedUrl.pathname);
  apiProxy.web(req, res, {target: config[proxyTarget]});
});

// 在代理返回时,注入 saveApi 方法
apiProxy.on('proxyRes', function (proxyRes, req, res) {
  apiMock.saveApi(req, res, proxyRes.headers['content-encoding']);
});

// 以下为针对 post 请求,代理消费了 stream 的情况
// 针对 post 请求,将 (express.js)bodyParser 消费过的 stream 重新写回到 req
apiProxy.on('proxyReq', function(proxyReq, req, res, options) {
  if (!req.body || !Object.keys(req.body).length) {
    return;
  }

  const contentType = proxyReq.getHeader('Content-Type');
  let bodyData;

  if (contentType === 'application/json') {
    bodyData = JSON.stringify(req.body);
  }

  if (contentType === 'application/x-www-form-urlencoded') {
    bodyData = queryString.stringify(req.body);
  }

  if (bodyData) {
    proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
    proxyReq.write(bodyData);
  }
});

mock 规则

简单 mock 的规则为:

  • 请求 URL 路径中将 / 替换为 _ 作为文件名,以 js 结尾。例如,请求 URL 为 /a/b/c,则对应的文件名应当为 a_b_c.js
  • 关于规则文件:
    • 导出内容可为普通对象或数组、字符等,将直接作为 API 返回内容
    • 导出内容可为函数,函数传入参数 req 和 req 对象。此时:
      • 可根据 req.query 处理不同的返回内容;
      • 可直接处理返回信息。如: res.status(200).send(content)res.status(403).send('禁止访问')(模拟出错)
  • mockdata 目录为常用的公共 API,会提交至 GIT 仓库
  • customdata 目录为本地自定义 API,不会提交至 GIT 仓库。并且该目录内容优先级大于 mockdata 目录
  • 不 mock 的情况(代理至后端 API):
    • 符合规则的文件不存在
    • 文件导出内容为 undefinednull 或者 __ignore_mock__

mock 文件查找规则:

  • 先查找 ${config.mockFileDir}/customdata 目录
  • 再查找 ${config.mockFileDir}/mockdata 目录
  • 最后查找 ${config.mockFileDir}/customdata/autosave 目录
  • 都没有,则走转发到真实 API 代理。如果开启了自动保存,则会将返回结果保存到 autosave 目录中

配置与 API

开启/关闭 mock 的配置方法

  • 配置文件方式

项目根目录 simple-mock-config.js 为配置文件,应自行创建,并配置 .gitignore 中忽略它,以便于随时修改 mock 行为而不影响其他开发者。配置内容示例参考:

module.exports = {
  mockFileDir: 'mock', // path.contentlove(__dirname, 'mock'), // 指定 mock 文件存放的目录
  isEnableMock: false, // 是否开启 Mock API 功能
  isAutoSaveApi: true, // 是否自动保存远端请求的 API
  isForceSaveApi: false, // 是否强制保存,否则本地有时不再保存
  // 自动保存 API 返回内容时,对内容进行过滤的方法,返回为 true 才保存
  fnAutosaveFilter(content) {
    // 示例: 不保存 content.data.length = 0 的数据
    if (content && Array.isArray(content.data) && !content.data.length) {
      return false;
    }

    return true;
  }
};
  • 环境变量方式

环境变量重要用于开启或关闭相关功能。其开启功能的优先级高于 simple-mock-config.js 中的配置。

  • 开启MOCK功能 process.env.MOCKAPI_ENABLE=mock
  • 开启自动保存API返回内容 process.env.MOCKAPI_AUTOSAVE=save
  • 强制每次请求都保存API返回内容(未开启MOCK功能时有效,一般不推荐开启) process.env.MOCKAPI_AUTOSAVE_FORCE=force
# 开启MOCK功能
set MOCKAPI_ENABLE=mock # process.env.MOCKAPI_ENABLE=mock
# 开启自动保存API返回内容
set MOCKAPI_AUTOSAVE=save # process.env.MOCKAPI_AUTOSAVE=save
# 强制每次请求都保存API返回内容(未开启MOCK功能时有效,一般不推荐开启)
set MOCKAPI_AUTOSAVE_FORCE=force # process.env.MOCKAPI_AUTOSAVE_FORCE=force

API

  • render(req, res, apiPath?): Promise<boolean>

判断一个请求是否可 mock,如果满足条件则执行 mock 逻辑。 应在 nodejs 服务中代理转发前执行。返回一个 Promise,结果为 true 则表示可 mock,停止继续执行代理转发;否则为不 mock,应继续走代理转发逻辑。 reqres 会传递到 mocK 规则文件中的自定义规则函数参数中,可通过 reqres 参数自行处理 mock 数据逻辑。

  • saveApi(req, res, contentEncoding)

在代理请求返回时执行,以判定是否需要保存后端返回的 API 数据。

注意: contentEncoding 取值为 encoded 时, res 应为需要直接保存的 JSON 格式的内容。如:

simpleMock.saveApi(req, {user: 'zhansan'}, 'encoded');

FAQ / MOCK规则编写示例与技巧

  • 如何保存通过代理返回的信息?

关闭 mock 功能,开启自动保存API功能:

process.env.MOCKAPI_ENABLE=N
process.env.MOCKAPI_AUTOSAVE=save
  • 在开启 mock 模式下,如何忽略某个 API 请求的 mock,从真实后端 API 去请求?

mock/customdata目录中,编辑该 API 对应的 mock 文件,将返回值改为 __ignore_mock__。如果需要根据参数来处理,也是可以实现的,示例:

// 忽略mock
module.exports = '__ignore_mock__';
// or
module.exports = req => {
  const query = Object.assign({}, req.query, req.body);
  // id 为 1 则不 mock
  if (+query.id === 1) {
    return '__ignore_mock__';
  }

  return {...};
}
  • 小技巧:对于同一 API,如何快速保存不同参数返回的不同的值?

简单的数据返回,在 customdata 目录下自行写逻辑即可。但对于不同参数返回结果复杂,且差异巨大。这种情况下,自行写逻辑就变得繁琐。

此时可关闭mock,开启自动保存和强制保存:

module.exports = {
  mockFileDir: 'mock',
  isEnableMock: false,
  isAutoSaveApi: true,
  isForceSaveApi: true,
}

然后每触发一次请求成功后,到customdata/autosave 中找到返回内容,复制出来,如此即可快速得到不同的返回值,再到customdata 中根据不同参数定义不同的返回逻辑。

  • mock 模式下,API 对应 mock 文件不存在时,会转发至后端。但此时会报错?

登陆信息为 mock 返回,session 为无效信息,转发至后端登陆认证失败,API 请求自然也不会成功。 此时可关闭 mock 功能,正常登陆一次,再开启mock;也可临时关闭登陆相关 API 的 mock。

  • 忽略自定义目录 customdata 的内容,使用公共目录下的 mockdata?

当 customdata 目录下有符合的规则时,会优先使用,否则则使用 mockdata 下的规则定义。因此,删除 customdata 目录下的定义即可。 但是因为开启 saveApi 会自动保存到 customdata,所以还有一种办法,就是在该目录下的文件中导出值为 undefined

module.exports = void(0);
  • saveApi 保存的某 API 的内容陈旧怎么办?

手动修改对应 mock 数据规则符合你的需要,或者删除相关文件,以重新自动保存远端请求的结果。

  • more...

开发与测试

git clone https://github.com/lzwme/simple-mock.git
cd simple-mock
yarn start

其他相关

simple-mock's People

Contributors

renxia avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.