使用 Node 的简单 API 模拟工具






4.33/5 (2投票s)
一份在 Node 中创建 API 模拟工具的指南
引言
- 你的工作是否依赖于他人的 API?
- 由于 API 不可用,你的工作是否被延误?
- 你是否对开发 Node.js 工具感兴趣?
如果以上任何一个问题的答案是“是”,那么这篇文章就是为你准备的。
背景
API 的不断变化会破坏端点,还会消耗部署时间。这些 API 的变化会延迟前端团队的工作。因此,我考虑使用一些 API Mocking 工具,但所有这些工具都有自己的学习曲线。这促使我快速创建了一个简单明了的 API Mocking 工具。
关于该工具
该工具可帮助开发人员独立于 API 的可用性继续他们的任务。开发人员只需将所有 API 请求路由到该工具,它就会缓存响应,并在出错时返回 Mocked 响应。
用途
-
安装
api-mock-proxy
npm install -g api-mock-proxy
-
现在,你可以这样运行你的 Mock Proxy:
api-mock-proxy -p 8000 -t http://your.api.com
现在你的代理服务器已在 https://:8000 准备就绪。只需在所有客户端中使用此 URL,你将从 http://your.api.com 获取响应。最棒的是,如果实际 API 不起作用,它将返回 Mocked 响应。
可用选项
-
port 或 -p: (默认:8080)
- 指定 Mock 服务器将监听的端口 -
targetUrl 或 -t: (默认:https://:80)
- 指定 Mock 服务器将转发所有请求并返回响应的目标 URL。这将是你的实际 API 的 URL,Mock 服务器将保存响应以便在 API 响应错误时进行 Mock。 -
errorCodes 或 -e: (默认:*)
- 这将提供 Mocking 错误的选项,错误代码将以逗号分隔的列表提供,例如404,500,ECONNREFUSED
默认值为*
,这意味着它将为任何错误返回 Mocked 响应,除非处于录制模式。 mode 或 -m: (默认:mix)
- 它可以接受三个值中的任何一个mock
|record
|mix
mock
: Mock 所有请求,无需调用实际 APIrecord
: 始终从实际 API 返回响应并创建缓存以备将来 Mockmix
: 调用实际 API 并返回实际响应,除了传递给mockedError
的错误代码。
-
dataPath 或 -d: (默认:./data.json)
- Mock 数据路径,它应该是有效的数据文件。第一次,只需指定路径,Mock 将在此位置创建。要运行 Mock 模式,必须预先填充 Mock 数据。 -
--cors
- 使用此选项为所有来源、方法和标头启用 CORS 标头 -
allowOrigin
- 提供一个string
以用于响应标头 'Access-Control-Allow-Origin
' -
allowMethods
- 提供一个string
以用于响应标头 'Access-Control-Allow-Methods
' -
allowHeaders
- 提供一个string
以用于响应标头 'Access-Control-Allow-Headers
' -
sslKey
- 提供一个string
作为 HTTPS 服务器的Key
,只有同时提供了密钥和证书才会创建 HTTPS 服务器 -
sslCert
- 提供一个string
作为 HTTPS 服务器的证书 -
keyFile
- 提供一个 Key 文件的路径,用于 HTTPS 服务器 -
certFile
- 提供一个 Certificate 文件的路径,用于 HTTPS 服务器
关于代码
代码按以下简单步骤编写:
- 读取用户输入或命令行参数
- 根据传递的参数创建 HTTP 服务器
- 请求目标服务器
- 返回实际或 Mocked 响应
现在我们将逐一理解。
处理命令行参数
有很多 NPM 包可用于处理命令行参数,例如 yargs、commander 等,但为了保持最少的依赖,该工具在没有任何第三方库的情况下处理命令行参数。Node.js 在一个数组中提供了所有命令行参数,可以轻松处理。例如,命令 api-mock-proxy -p 8000 -t http://your.api.com
将在你的程序中接收参数,如下所示:
[ 'C:\\Program Files\\nodejs\\node.exe',
'C:\Users\admin\AppData\Roaming\npm\node_modules\api-mock-proxy',
'-p',
'8000',
'-t',
'http://your.api.com' ]
注意数组的前两个元素,它们是 node
和 package
的路径,所以参数应该从数组的第三个元素开始。
参数处理的另一个重要部分是提供默认值,因此为此使用了 lodash,这是一个用于所有此类任务的实用库。
const options = _.defaults(getOptions(myArgs), defaults);
创建代理服务器
处理完所有参数后,我们就准备好根据提供的选项创建代理服务器了。用户可以选择创建 HTTP
或 HTTPS
服务器,这可以通过使用原生的 Node.js 模块来完成:
const createServer = options.ssl ? _.curry(https.createServer)(sslOptions) : http.createServer;
const server = createServer((req, res) => {
// Request handling here
}
sslOptions
包含 HTTPS
服务器的密钥和证书。
创建服务器后,一个重要部分是设置响应标头,如通过 CORS
相关标头或通过 --cors
标志在选项中提供的。
请求目标服务器
现在,下一步是将请求转发到目标服务器。如果用户没有选择仅通过使用 -m mock
或 --mode mock
来接收 Mocked 响应。服务器的每个响应将被存储为 Mocked 数据以供将来使用。响应将针对三个键进行保存,第一个是整个请求对象的哈希,第二个是去掉标头的请求的哈希,第三个是去掉标头和正文的请求的哈希。这样,我们就可以用最少的细节获取匹配的 Mocked 响应。
const fullHash = getHash(req);
const withOutHeader = getHash({ ...req, headers: "" });
const minHash = getHash({ ...req, headers: "", body: "" });
提供响应
对任何请求的实际响应将取决于用户的偏好。如果用户正在运行录制模式(-m record
或 --mode record
)或混合模式下的无错误响应(-m mix
或 --mode mix
或不提供此选项),则在保存目标服务器响应后,将其转发。如果用户正在运行 Mock 模式(-m mock
或 --mode mock
),或者目标服务器响应了 -e
404,500
,ECONNREFUSED
或 --
errorCodes
*
指定的错误代码,则将返回 Mocked 响应。
要从 Mocked 数据中获取 Mocked 响应,第一步是找到在保存请求时创建的三个哈希请求键之一的响应。
for (let i = 0; i < reqHash.length; i++) {
const item = reqHash[i];
const existing = data[item];
if (existing) {
if (existing.length == 0) {
return existing[0].res;
}
return findBestMatch(existing, reqObj);
}
}
如果哈希返回多个值,则它将使用 epsilonjs 找到最佳匹配,这是一个近似 string
匹配库,并且在整个数据中也使用相同的库,前提是哈希未找到匹配项。
const findBestMatch = (data, matchObj) => {
const diffIndex = data.map(item => {
return epsilon.leven(JSON.stringify(matchObj), JSON.stringify(item.req));
});
const minIndex = diffIndex.indexOf(Math.min(...diffIndex));
const mock = data[Math.max(minIndex, 0)];
return (mock || {}).res;
};
关注点
- 在 Node.js 中创建工具非常简单。
- 在你的主文件(package.json 的 main 键中指定的文件)的第一行添加
#!/
usr
/bin/env node
,以使你的 Node.js 文件可执行。 - Node.js 将前两个参数作为 Node.js 可执行文件和正在执行的包/文件路径传递。
历史
下一步对于该工具很重要,那就是提供 UI 来创建 Mock 数据。