Skip to content

子项装饰器

基本介绍

awe-axios定义了一些子项装饰器,这些装饰器就像是语法糖一样,可以让用户更加方便的去进行配置。我们来看一个案例:

ts
@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中分离:

ts
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实例对象作为配置项,如下所示:

ts
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);

配置优先级

子装饰器的配置小于直接在父类装饰器中直接配置,也就是说:

ts
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实例对象作为配置项,如下所示:

ts
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也可以在父类装饰器中配置,子项装饰器的配置优先级仍然小于父类装饰器的配置,如下所示:

ts
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一致,它接受一个处理函数或数组,数组中的每一项都是一个函数,函数的返回值将下一个函数的输入,最后一个函数的返回将作为最终响应数据,如下所示:

ts
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 {}
}

执行顺序以及合并策略

  1. @TransformResponse中的每个函数是自上而下执行的
  2. 如果@Get中配置了transformResponse,则会与@TransformResponse合并,且@Get中的函数会在@TransformResponse中的函数之前执行`

@TransformRequest

这个装饰器是一个方法装饰器,用于设置请求数据处理器,与axios中的transformRequest一致,它接受一个处理函数或数组,数组中的每一项都是一个函数,函数的返回值将作为下一个函数的输入,最后返回作为请求数据,如下所示:

ts
@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);

执行顺序以及合并策略

  1. @TransformRequest中的每个函数是自上而下执行的
  2. 如果@Post中配置了transformRequest,则会与@TransformRequest合并,且@Post中的函数会在@TransformRequest中的函数之前执行`

更多子项装饰器

目前只提供了这四种装饰器,后续会陆续增加更多的子项装饰器,欢迎大家提出宝贵意见。