简单说说前端项目中可用的 API Mocking 策略
在 dev.to 上看到一篇文章《API Mocking Strategies for JavaScript Applications》,介绍前端项目中的 API Mocking 策略,阅读后有些收获,在这里给大家做下简单概述。
传统 Mock 的两个可选方向
网页中一个典型的网页请求是这样的:
如果要对我们的项目下手进行 Mock,有两个可选的方向。一个是 Mock Request Client(window.fetch 或 window.XMLHttpRequest),一个是 Mock 服务器。
Mock Request Client
对 Mock Request Client 而言,其原理比较简单,类似下面这样:
window.fetch = (init, input) => {
// Respond with a mocked response
// any time our code calls "window.fetch".
return new Response('hello')
}
就是重写了 Fetch API,请求并不会真的发送,浏览器中也不会看到请求发出。效果类似下面这样:
像下面这些库都是使用的这个策略:
网页端是通过重写 window.fetch
/window.XMLHttpRequest
,而 Node.js 端则是通过重写 http/https 模块来实现请求拦截 Mock 的。
Mock 服务器
Mock Request Client 的在浏览器上的一个明显弊端,就是其实我们并没有真正调用 Fetch API/XMLHttpRequest API,就直接返回 Mock 结果了。
因此,我们有了一个可选方案,就是去替换请求路径中的 server 部分,变成这样:
反馈到代码上,我们就要这样写:
const IS_TEST = process.env.NODE_ENV === 'test'
fetch(
IS_TEST
// Communicate with a local mock server while testing.
? 'http://localhost:3000/api'
: 'https://api.backend.com'
)
这就有点类似测试环境服务器了。虽然解决了能走到请求 API、看到请求的问题,这里列举了一些,可以用作这类似用途的库。
但是这需要我们多加一个判断条件,增加了一个 Mock 服务器,多了编写和维护的服务器的运营成本。
因此,选择那种方案,我们要根据实际情况,去做取舍。
如果我们把前端项目中的请求分成:客户端(浏览器)请求和服务端请求。虽然,服务端请求现在还是只能老一套,只能通过重写 http/https 模块来实现请求拦截和 Mock,那么客户端请求因为有了 Service Worker 的介入带来了 Mock 曙光。
客户端请求 Mock 新方式:Service Worker API
Service Worker API 可以实现客户端请求的 Mock 新方式:在能看到网页请求发出的同时(开发者工具中能看到请求地址),还能做请求响应数据的 Mock。
简单点说,就是监听网页中的 fetch 事件。
// main.js
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
// 注册 Service Worker
navigator.serviceWorker.register('/service-worker.js')
.then(function(registration) {
console.log('Service Worker registered with scope:', registration.scope);
})
.catch(function(error) {
console.log('Service Worker registration failed:', error);
});
});
}
// service-worker.js
// 拦截请求(fetch 事件会在网页中每发生一次数据请求时触发)
self.addEventListener('fetch', event => {
event.respondWith(
new Response('Hello from the Service Worker!')
);
});
体实现原理,可以参考这篇文章:《Use Service Workers to manage network requests》
而 Mock Service Worker(又叫 mwsjs)就是通过 Service Worker API 来做客户端请求 Mock 的(当然服务端还是借助重写 http
/https
模块的方式)。
import { setupWorker, rest } from 'msw'
const worker = setupWorker(
rest.post('/login', async (req, res, ctx) => {
const { username } = await req.json()
return res(
ctx.json({
username,
firstName: 'John'
})
)
}),
)
worker.start()
关于 mwsjs 的使用,可以参考我写的文章《mswjs:在浏览器和 Node 环境中轻松做 API Mocking》了解。
感谢你阅读到这里,Happy Coding!
转载自:https://juejin.cn/post/7250318612510195769