Skip to content

Commit a42cc21

Browse files
authored
refactor(middleware): close #27, regenerate reqFnParams (#28)
1 parent 131c98f commit a42cc21

File tree

6 files changed

+72
-37
lines changed

6 files changed

+72
-37
lines changed

docs/guide/middleware.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,17 @@ async function (ctx, next) {
5353
| 已使用的属性名 | 含义和作用 |
5454
| --- | --- |
5555
| req | 请求 |
56-
| req.reqFnParams | 发起请求所需的配置 |
57-
| req.reqFnParams.reqParams | 请求的数据对象 |
56+
| req.host | 服务器地址 |
57+
| req.mock | 模拟的响应数据或是生成数据的函数 |
58+
| req.type | 接口请求类型 get/post... |
59+
| req.path | 接口结尾路径 |
60+
| req.prefix | 接口前缀 |
61+
| req.reqType | 使用什么工具发(axios/jsonp/wx) |
62+
| req.reqParams | 已添加默认参数的请求参数 |
63+
| req.callbackName | 使用 jsonp 时的回调函数名 |
64+
| req.axiosOptions | 透传 axios 配置参数 |
65+
| req.jsonpOptions | 透传 fetch-jsonp 配置参数|
66+
| req.reqFnParams | 发起请求时的参数对象(上面那些参数都会被放进来作为属性) |
5867
| --- | --- |
5968
| res | 响应 |
6069
| res.data | 响应的数据 |

examples/apis-web/fake-post.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,21 @@ export default {
3131
reqType: 'axios',
3232
params: ['param1', 'param2'],
3333
},
34+
/**
35+
* array-params with new host
36+
*/
37+
{
38+
name: 'hap',
39+
path: 'array-params',
40+
type: 'post',
41+
reqType: 'axios',
42+
middleware: [
43+
async (ctx, next) => {
44+
ctx.req.host = 'http://custom-host.com/'
45+
await next()
46+
},
47+
],
48+
},
3449
/**
3550
* object-params
3651
*/

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "tua-api",
3-
"version": "1.0.1",
3+
"version": "1.1.0",
44
"description": "🏗 A common tool helps converting configs to api functions",
55
"main": "dist/TuaApi.cjs.js",
66
"module": "dist/TuaApi.esm.js",

src/TuaApi.js

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ import {
1919
getFetchJsonpPromise,
2020
} from './adapters/'
2121
import {
22-
setFullUrlMiddleware,
2322
formatResDataMiddleware,
2423
recordReqTimeMiddleware,
24+
setReqFnParamsMiddleware,
2525
recordStartTimeMiddleware,
2626
formatReqParamsMiddleware,
2727
} from './middlewareFns'
@@ -92,31 +92,37 @@ class TuaApi {
9292
/**
9393
* 根据 reqType 和 type 决定调用哪个库
9494
* @param {Object} options
95+
* @param {Object|Function} options.mock 模拟的响应数据或是生成数据的函数
9596
* @param {String} options.url 接口地址
9697
* @param {String} options.type 接口请求类型 get/post...
9798
* @param {String} options.fullUrl 完整接口地址
98-
* @param {String} options.path 接口路径名称
99+
* @param {String} options.reqType 使用什么工具发(axios/jsonp/wx)
100+
* @param {Object} options.reqParams 请求参数
101+
* @param {String} options.callbackName 使用 jsonp 时的回调函数名
102+
* @param {Object} options.axiosOptions 透传 axios 配置参数
103+
* @param {Object} options.jsonpOptions 透传 fetch-jsonp 配置参数
99104
* @return {Promise}
100105
*/
101106
_reqFn ({
102107
url,
108+
mock,
103109
type,
104110
fullUrl,
105111
reqType,
106112
reqParams: data,
107113
callbackName,
108-
jsonpOptions,
109114
axiosOptions,
115+
jsonpOptions,
110116
...rest
111117
}) {
112118
// check type
113119
this._checkReqType(reqType)
114120

115121
// mock data
116-
if (rest.mock) {
117-
const resData = typeof rest.mock === 'function'
118-
? rest.mock(data)
119-
: { ...rest.mock }
122+
if (mock) {
123+
const resData = typeof mock === 'function'
124+
? mock(data)
125+
: { ...mock }
120126

121127
return Promise.resolve({ data: resData })
122128
}
@@ -175,7 +181,7 @@ class TuaApi {
175181
// 业务侧中间件函数数组
176182
...middlewareFns,
177183
// 生成 fullUrl 参数
178-
setFullUrlMiddleware,
184+
setReqFnParamsMiddleware,
179185
// 统一转换响应数据为对象
180186
formatResDataMiddleware,
181187
// 记录结束时间
@@ -199,7 +205,7 @@ class TuaApi {
199205
* @param {String} options.type 接口请求类型 get/post...
200206
* @param {Object|Function} options.mock 模拟的响应数据或是生成数据的函数
201207
* @param {String} options.name 自定义的接口名称
202-
* @param {String} options.path 接口路径名称
208+
* @param {String} options.path 接口结尾路径
203209
* @param {String[]} options.params 接口参数数组
204210
* @param {String} options.prefix 接口前缀
205211
* @param {Function} options.afterFn 在请求完成后执行的钩子函数(将被废弃)
@@ -227,7 +233,6 @@ class TuaApi {
227233
}) {
228234
// 优先使用 name
229235
const apiName = name || path
230-
const fullPath = `${prefix}/${path}`
231236

232237
// 合并全局默认值
233238
rest.host = rest.host || this.host
@@ -253,7 +258,7 @@ class TuaApi {
253258
args = args === null ? {} : args
254259

255260
// 最终的运行时配置,runtimeOptions 有最高优先级
256-
const runtimeParams = { type, path, params, prefix, apiName, fullPath, ...rest, ...runtimeOptions }
261+
const runtimeParams = { type, path, params, prefix, apiName, ...rest, ...runtimeOptions }
257262

258263
// 自定义回调函数名称(用于 jsonp)
259264
runtimeParams.callbackName = runtimeParams.callbackName || `${runtimeParams.path}Callback`
@@ -292,7 +297,7 @@ class TuaApi {
292297
)
293298
}
294299

295-
apiFn.key = fullPath
300+
apiFn.key = `${prefix}/${path}`
296301
apiFn.mock = mock
297302
apiFn.params = params
298303

src/middlewareFns.js

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,8 @@ const formatResDataMiddleware = (ctx, next) => next().then(() => {
5656
const formatReqParamsMiddleware = (ctx, next) => {
5757
const {
5858
args,
59-
host,
6059
params,
61-
fullPath,
6260
commonParams,
63-
...rest
6461
} = ctx.req
6562

6663
if (typeof args !== 'object') {
@@ -70,45 +67,43 @@ const formatReqParamsMiddleware = (ctx, next) => {
7067
checkArrayParams(ctx.req)
7168

7269
// 根据配置生成请求的参数
73-
const reqParams = Array.isArray(params)
70+
ctx.req.reqParams = Array.isArray(params)
7471
? { ...commonParams, ...args }
7572
: { ...getDefaultParamObj(ctx.req), ...args }
7673

77-
// 请求地址
78-
const url = host + fullPath
79-
80-
ctx.req.reqFnParams = {
81-
...ctx.req.reqFnParams,
82-
...rest,
83-
url,
84-
reqParams,
85-
}
86-
8774
return next()
8875
}
8976

9077
/**
91-
* 设置请求 fullUrl 参数
78+
* 设置请求的 reqFnParams 参数,将被用于 _reqFn 函数
9279
* @param {Object} ctx 上下文对象
9380
* @param {Function} next 转移控制权给下一个中间件的函数
9481
*/
95-
const setFullUrlMiddleware = (ctx, next) => {
96-
const { url, reqParams } = ctx.req.reqFnParams
82+
const setReqFnParamsMiddleware = (ctx, next) => {
83+
const { path, host, prefix, reqParams, ...rest } = ctx.req
9784

85+
// 请求地址
86+
const url = host + prefix + '/' + path
9887
const paramsStr = getParamStrFromObj(reqParams)
99-
10088
// 完整请求地址,将参数拼在 url 上,用于 get 请求
101-
ctx.req.reqFnParams.fullUrl = paramsStr
102-
? url + '?' + paramsStr
103-
: url
89+
const fullUrl = paramsStr ? `${url}?${paramsStr}` : url
90+
91+
ctx.req.reqFnParams = {
92+
url,
93+
fullUrl,
94+
reqParams,
95+
...rest,
96+
// 若是用户自己传递 reqFnParams 则优先级最高
97+
...ctx.req.reqFnParams,
98+
}
10499

105100
return next()
106101
}
107102

108103
export {
109-
setFullUrlMiddleware,
110104
recordReqTimeMiddleware,
111105
formatResDataMiddleware,
106+
setReqFnParamsMiddleware,
112107
recordStartTimeMiddleware,
113108
formatReqParamsMiddleware,
114109
}

test/__tests__/axios.test.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,17 @@ const reqTAUrl = `http://example-base.com/fake-get/req-type-axios?asyncCp=asyncC
1818
const reqEAPUrl = `http://example-base.com/fake-post/empty-array-params`
1919
const reqMFDUrl = `http://example-base.com/fake-get/mock-function-data`
2020

21+
describe('middleware', () => {
22+
test('change host before request', async () => {
23+
const data = { code: 0, data: 'custom host' }
24+
const reqHAPUrl = `http://custom-host.com/fake-post/array-params`
25+
mock.onPost(reqHAPUrl).reply(200, data)
26+
const resData = await fakePostApi.hap()
27+
28+
expect(resData).toEqual(data)
29+
})
30+
})
31+
2132
describe('mock data', () => {
2233
test('mock function data', async () => {
2334
mock.onGet(reqMFDUrl).reply(200, {})

0 commit comments

Comments
 (0)