子项装饰器
基本介绍
awe-axios定义了一些子项装饰器,这些装饰器就像是语法糖一样,可以让用户更加方便的去进行配置。我们来看一个案例:
@HttpApi({
refAxios: request,
})
class UserApi {
@Get({
url: '/pages',
transformResponse: [
data => {
// handle1
return data;
},
data => {
// handle2
return data;
},
],
})
getUserPages(): any {}
}可以看到我们所有的http请求配置项都配置再@Get中,这会导致配置十分臃肿,于是awe-axios定义了一些子项装饰器,用来让配置结构更加清晰,比如下面我们使用了@TransformResponse将响应数据处理器从@Get中分离:
const request = axiosPlus.create({
baseURL: 'http://localhost:3000/users/',
});
@HttpApi({
refAxios: request,
})
class UserApi {
@Get({
url: '/pages',
})
@TransformResponse([
data => {
return JSON.parse(data).data;
},
data => {
data = data.map((user: any) => {
user['age'] = 12;
return user;
});
return data;
},
])
getUserPages(@QueryParam('page') page: number, @QueryParam('size') size: number): any {}
}
const { data } = await new UserApi().getUserPages(1, 3);
console.log(data);实际上awe-axios还有其它的子项装饰器,比如:@RefAxios,@AxiosRef等
@RefAxios
这个装饰器是一个类子装饰器,用于设置该类所有http接口所引用的axios实例,它接受一个axios实例对象作为配置项,如下所示:
const request = axiosPlus.create({
baseURL: 'http://localhost:3000/users/',
});
@HttpApi()
@RefAxios(request)
class UserApi {
@Get({
url: '/pages',
})
getUserPages(@QueryParam('page') page: number, @QueryParam('size') size: number): any {}
}
// 最终发送接口为http://localhost:3000/users/pages?size=3&page=1
const { data } = await new UserApi().getUserPages(1, 3);
console.log(data);配置优先级
子装饰器的配置小于直接在父类装饰器中直接配置,也就是说:
const request1 = axiosPlus.create({
baseURL: 'http://localhost:3000/users/',
});
const request2 = axiosPlus.create({
baseURL: 'http://localhost:3000/orders/',
});
@HttpApi({
refAxios: request1,
})
@RefAxios(request2)
class UserApi {
@Get({
url: '/pages',
})
getUserPages(@QueryParam('page') page: number, @QueryParam('size') size: number): any {}
}
// 最终发送接口为http://localhost:3000/users/pages?size=3&page=1
const { data } = await new UserApi().getUserPages(1, 3);
console.log(data);最终发送的接口为http://localhost:3000/users/pages?size=3&page=1,而不是http://localhost:3000/orders/pages?size=3&page=1
注意
同时要注意,@RefAxios需要依托@HttpApi装饰器,也就是说@HttpApi不可缺少,否则会报错。
@AxiosRef
这个装饰器是一个方法装饰器,用于设置该方法所引用的axios实例,它接受一个axios实例对象作为配置项,如下所示:
const request = axiosPlus.create({
baseURL: 'http://localhost:3000/users/',
});
class UserApi {
@Get({
url: '/pages',
})
@AxiosRef(request)
getUserPages(@QueryParam('page') page: number, @QueryParam('size') size: number): any {}
}
// 最终发送接口为http://localhost:3000/users/pages?size=3&page=1
const { data } = await new UserApi().getUserPages(1, 3);
console.log(data);可以看到使用了@AxiosRef甚至都不再需要使用@HttpApi了,因为@AxiosRef会直接为getUserPages绑定一个axios实例。
同时,@AxiosRef也可以在父类装饰器中配置,子项装饰器的配置优先级仍然小于父类装饰器的配置,如下所示:
const request1 = axiosPlus.create({
baseURL: 'http://localhost:3000/users/',
});
const request2 = axiosPlus.create({
baseURL: 'http://localhost:3000/orders/',
});
class UserApi {
@Get({
url: '/pages',
refAxios: request1,
})
@AxiosRef(request2)
getUserPages(@QueryParam('page') page: number, @QueryParam('size') size: number): any {}
}
// 最终发送接口为http://localhost:3000/orders/pages?size=3&page=1
const { data } = await new UserApi().getUserPages(1, 3);
console.log(data);总结配置优先级
@Get中配置> @AxiosRef装饰器配置> @HttpApi装饰器配置> @RefAxios装饰器配置
@TransformResponse
这个装饰器是一个方法装饰器,用于设置响应数据处理器,与axios中的transformResponse一致,它接受一个处理函数或数组,数组中的每一项都是一个函数,函数的返回值将下一个函数的输入,最后一个函数的返回将作为最终响应数据,如下所示:
const request = axiosPlus.create({
baseURL: 'http://localhost:3000/users/',
});
class UserApi {
@Get({
url: '/pages',
})
@TransformResponse([
// 1. 直接获取data数
data => {
return JSON.parse(data).data;
},
// 2. 增加age属性
data => {
data = data.map((user: any) => {
user['age'] = 12;
return user;
});
return data;
},
])
getUserPages(@QueryParam('page') page: number, @QueryParam('size') size: number): any {}
}执行顺序以及合并策略
@TransformResponse中的每个函数是自上而下执行的- 如果
@Get中配置了transformResponse,则会与@TransformResponse合并,且@Get中的函数会在@TransformResponse中的函数之前执行`
@TransformRequest
这个装饰器是一个方法装饰器,用于设置请求数据处理器,与axios中的transformRequest一致,它接受一个处理函数或数组,数组中的每一项都是一个函数,函数的返回值将作为下一个函数的输入,最后返回作为请求数据,如下所示:
@HttpApi('http://localhost:3000/users/')
class UserApi {
@Post({
url: '/',
})
@TransformRequest([
// 为user添加属性sex
data => {
data.sex = '男';
return data;
},
data => {
data.email = '1111@11.com';
return JSON.stringify(data);
},
])
createUser(@BodyParam() user: { name: string; age: number }): any {}
}
const { data } = await new UserApi().createUser({ name: 'test', age: 18 });
console.log(data);执行顺序以及合并策略
@TransformRequest中的每个函数是自上而下执行的- 如果
@Post中配置了transformRequest,则会与@TransformRequest合并,且@Post中的函数会在@TransformRequest中的函数之前执行`
更多子项装饰器
目前只提供了这四种装饰器,后续会陆续增加更多的子项装饰器,欢迎大家提出宝贵意见。