Skip to content

Commit

Permalink
refactor(middleware): close #27, regenerate reqFnParams (#28)
Browse files Browse the repository at this point in the history
  • Loading branch information
BuptStEve authored Apr 4, 2019
1 parent 131c98f commit a42cc21
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 37 deletions.
13 changes: 11 additions & 2 deletions docs/guide/middleware.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,17 @@ async function (ctx, next) {
| 已使用的属性名 | 含义和作用 |
| --- | --- |
| req | 请求 |
| req.reqFnParams | 发起请求所需的配置 |
| req.reqFnParams.reqParams | 请求的数据对象 |
| req.host | 服务器地址 |
| req.mock | 模拟的响应数据或是生成数据的函数 |
| req.type | 接口请求类型 get/post... |
| req.path | 接口结尾路径 |
| req.prefix | 接口前缀 |
| req.reqType | 使用什么工具发(axios/jsonp/wx) |
| req.reqParams | 已添加默认参数的请求参数 |
| req.callbackName | 使用 jsonp 时的回调函数名 |
| req.axiosOptions | 透传 axios 配置参数 |
| req.jsonpOptions | 透传 fetch-jsonp 配置参数|
| req.reqFnParams | 发起请求时的参数对象(上面那些参数都会被放进来作为属性) |
| --- | --- |
| res | 响应 |
| res.data | 响应的数据 |
Expand Down
15 changes: 15 additions & 0 deletions examples/apis-web/fake-post.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,21 @@ export default {
reqType: 'axios',
params: ['param1', 'param2'],
},
/**
* array-params with new host
*/
{
name: 'hap',
path: 'array-params',
type: 'post',
reqType: 'axios',
middleware: [
async (ctx, next) => {
ctx.req.host = 'http://custom-host.com/'
await next()
},
],
},
/**
* object-params
*/
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "tua-api",
"version": "1.0.1",
"version": "1.1.0",
"description": "🏗 A common tool helps converting configs to api functions",
"main": "dist/TuaApi.cjs.js",
"module": "dist/TuaApi.esm.js",
Expand Down
29 changes: 17 additions & 12 deletions src/TuaApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ import {
getFetchJsonpPromise,
} from './adapters/'
import {
setFullUrlMiddleware,
formatResDataMiddleware,
recordReqTimeMiddleware,
setReqFnParamsMiddleware,
recordStartTimeMiddleware,
formatReqParamsMiddleware,
} from './middlewareFns'
Expand Down Expand Up @@ -92,31 +92,37 @@ class TuaApi {
/**
* 根据 reqType 和 type 决定调用哪个库
* @param {Object} options
* @param {Object|Function} options.mock 模拟的响应数据或是生成数据的函数
* @param {String} options.url 接口地址
* @param {String} options.type 接口请求类型 get/post...
* @param {String} options.fullUrl 完整接口地址
* @param {String} options.path 接口路径名称
* @param {String} options.reqType 使用什么工具发(axios/jsonp/wx)
* @param {Object} options.reqParams 请求参数
* @param {String} options.callbackName 使用 jsonp 时的回调函数名
* @param {Object} options.axiosOptions 透传 axios 配置参数
* @param {Object} options.jsonpOptions 透传 fetch-jsonp 配置参数
* @return {Promise}
*/
_reqFn ({
url,
mock,
type,
fullUrl,
reqType,
reqParams: data,
callbackName,
jsonpOptions,
axiosOptions,
jsonpOptions,
...rest
}) {
// check type
this._checkReqType(reqType)

// mock data
if (rest.mock) {
const resData = typeof rest.mock === 'function'
? rest.mock(data)
: { ...rest.mock }
if (mock) {
const resData = typeof mock === 'function'
? mock(data)
: { ...mock }

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

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

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

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

apiFn.key = fullPath
apiFn.key = `${prefix}/${path}`
apiFn.mock = mock
apiFn.params = params

Expand Down
39 changes: 17 additions & 22 deletions src/middlewareFns.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,8 @@ const formatResDataMiddleware = (ctx, next) => next().then(() => {
const formatReqParamsMiddleware = (ctx, next) => {
const {
args,
host,
params,
fullPath,
commonParams,
...rest
} = ctx.req

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

// 根据配置生成请求的参数
const reqParams = Array.isArray(params)
ctx.req.reqParams = Array.isArray(params)
? { ...commonParams, ...args }
: { ...getDefaultParamObj(ctx.req), ...args }

// 请求地址
const url = host + fullPath

ctx.req.reqFnParams = {
...ctx.req.reqFnParams,
...rest,
url,
reqParams,
}

return next()
}

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

// 请求地址
const url = host + prefix + '/' + path
const paramsStr = getParamStrFromObj(reqParams)

// 完整请求地址,将参数拼在 url 上,用于 get 请求
ctx.req.reqFnParams.fullUrl = paramsStr
? url + '?' + paramsStr
: url
const fullUrl = paramsStr ? `${url}?${paramsStr}` : url

ctx.req.reqFnParams = {
url,
fullUrl,
reqParams,
...rest,
// 若是用户自己传递 reqFnParams 则优先级最高
...ctx.req.reqFnParams,
}

return next()
}

export {
setFullUrlMiddleware,
recordReqTimeMiddleware,
formatResDataMiddleware,
setReqFnParamsMiddleware,
recordStartTimeMiddleware,
formatReqParamsMiddleware,
}
11 changes: 11 additions & 0 deletions test/__tests__/axios.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,17 @@ const reqTAUrl = `http://example-base.com/fake-get/req-type-axios?asyncCp=asyncC
const reqEAPUrl = `http://example-base.com/fake-post/empty-array-params`
const reqMFDUrl = `http://example-base.com/fake-get/mock-function-data`

describe('middleware', () => {
test('change host before request', async () => {
const data = { code: 0, data: 'custom host' }
const reqHAPUrl = `http://custom-host.com/fake-post/array-params`
mock.onPost(reqHAPUrl).reply(200, data)
const resData = await fakePostApi.hap()

expect(resData).toEqual(data)
})
})

describe('mock data', () => {
test('mock function data', async () => {
mock.onGet(reqMFDUrl).reply(200, {})
Expand Down

0 comments on commit a42cc21

Please sign in to comment.