@narando/nest-axios-interceptor
https://github.com/narando/nest-axios-interceptor
为 NestJS HttpModule/HttpService轻松构建和配置axios 拦截器。
特性
- 定义 axios 拦截器
HttpService.axiosRef
上的注册拦截器- 请求配置中自定义选项的类型安全处理
使用
⚠️ 如果你想在 NestJS 版本 6 或 7 中使用@narando/nest-axios-interceptor,请使用 v1 版本。 v2 版本只兼容 NestJS Version 8 和@nestjs/axios 包。
安装
安装这个模块:
创建一个 AxiosInterceptor
创建一个新模块并导入 HttpModule
:
TypeScript
// cats.module.ts
import { HttpModule, HttpService } from "@nestjs/axios";
@Module({
imports: [HttpModule],
providers: [HttpService],
})
export class CatsModule {}
用这个样板文件引导你的新拦截器:
TypeScript
// logging.axios-interceptor.ts
import { Injectable } from "@nestjs/common";
import { HttpService } from "@nestjs/axios";
import type { AxiosRequestConfig, AxiosResponse } from "axios";
import { AxiosInterceptor, AxiosFulfilledInterceptor, AxiosRejectedInterceptor } from "@narando/nest-axios-interceptor";
@Injectable()
export class LoggingAxiosInterceptor extends AxiosInterceptor {
constructor(httpService: HttpService) {
super(httpService);
}
// requestFulfilled(): AxiosFulfilledInterceptor<AxiosRequestConfig> {}
// requestRejected(): AxiosRejectedInterceptor {}
// responseFulfilled(): AxiosFulfilledInterceptor<AxiosResponse> {}
// responseRejected(): AxiosRejectedInterceptor {}
}
默认情况下,拦截器为所有 4 个可能的事件使用标识函数(no-op)。
要添加您的行为,覆盖您想要处理的事件的类方法,并返回一个将在拦截器中使用的函数。
TypeScript
// logging.axios-interceptor.ts
@Injectable()
export class LoggingAxiosInterceptor extends AxiosInterceptor {
constructor(httpService: HttpService) {
super(httpService);
}
requestFulfilled(): AxiosFulfilledInterceptor<AxiosRequestConfig> {
return (config) => {
// Log outgoing request
console.log(`Request: ${config.method} ${config.path}`);
return config;
};
}
// requestRejected(): AxiosRejectedInterceptor {}
// responseFulfilled(): AxiosFulfilledInterceptor<AxiosResponse> {}
// responseRejected(): AxiosRejectedInterceptor {}
}
为请求配置设置自定义选项
如果你想把数据从一个拦截器传递到另一个拦截器,把它添加到请求配置对象中。
首先,定义新的请求配置类型。为了避免与其他拦截器的冲突,我们将定义一个 Symbol,并将其用作 object 的键:
TypeScript
// logging.axios-interceptor.ts
const LOGGING_CONFIG_KEY = Symbol("kLoggingAxiosInterceptor");
// Merging our custom properties with the base config
interface LoggingConfig extends AxiosRequestConfig {
[LOGGING_CONFIG_KEY]: {
id: number;
};
}
现在我们必须更新拦截器来使用这个新的配置:
Diff
// logging.axios-interceptor.ts
@Injectable()
- export class LoggingAxiosInterceptor extends AxiosInterceptor {
+ export class LoggingAxiosInterceptor extends AxiosInterceptor<LoggingConfig> {
constructor(httpService: HttpService) {
super(httpService);
}
- requestFulfilled(): AxiosFulfilledInterceptor<AxiosRequestConfig> {
+ requestFulfilled(): AxiosFulfilledInterceptor<LoggingConfig> {
return (config) => {
// Log outgoing request
console.log(`Request: ${config.method} ${config.path}`);
return config;
};
}
// requestRejected(): AxiosRejectedInterceptor {}
- // responseFulfilled(): AxiosFulfilledInterceptor<AxiosResponse> {}
+ // responseFulfilled(): AxiosFulfilledInterceptor<AxiosResponseCustomConfig<LoggingConfig>> {}
// responseRejected(): AxiosRejectedInterceptor {}
}
有了更新的类型,你现在可以使用扩展配置:
TypeScript
// logging.axios-interceptor.ts
const LOGGING_CONFIG_KEY = Symbol("kLoggingAxiosInterceptor");
@Injectable()
export class LoggingAxiosInterceptor extends AxiosInterceptor<LoggingConfig> {
constructor(httpService: HttpService) {
super(httpService);
}
requestFulfilled(): AxiosFulfilledInterceptor<LoggingConfig> {
return (config) => {
const requestId = 1234;
config[LOGGING_CONFIG_KEY] = {
id: requestId,
};
// Log outgoing request
console.log(`Request(ID=${requestId}): ${config.method} ${config.path}`);
return config;
};
}
// requestRejected(): AxiosRejectedInterceptor {}
responseFulfilled(): AxiosFulfilledInterceptor<AxiosResponseCustomConfig<LoggingConfig>> {
return (response) => {
const requestId = response.config[LOGGING_CONFIG_KEY].id;
// Log response
console.log(`Response(ID=${requestId}): ${response.status}`);
return response;
};
}
// responseRejected(): AxiosRejectedInterceptor {}
}
处理错误
默认情况下,axios error (rejected)拦截器传递类型为any
的错误。这并不是很有用,因为我们不能用它做任何事情。
在内部, axios
将所有错误封装在一个自定义对象AxiosError
中。我们可以使用类方法 isAxiosError
来断言传递的错误确实是 AxiosError
类型的,然后按我们想要的方式处理它:
TypeScript
// logging.axios-interceptor.ts
@Injectable()
export class LoggingAxiosInterceptor extends AxiosInterceptor {
constructor(httpService: HttpService) {
super(httpService);
}
// requestFulfilled(): AxiosFulfilledInterceptor<AxiosRequestConfig> {}
// requestRejected(): AxiosRejectedInterceptor {}
// responseFulfilled(): AxiosFulfilledInterceptor<AxiosResponse> {}
responseRejected(): AxiosRejectedInterceptor {
return (err) => {
if (this.isAxiosError(err)) {
const { config, response } = err;
console.log(`Error ${response.status} in request "${config.method} ${config.path}`);
} else {
console.error("Unexpected generic error", err);
}
throw err;
};
}
}
许可证
此存储库是在MIT License下发布的。