Appearance
请求和响应拦截
SDK 支持一组 client 级 hooks,用来在请求发出前、返回结果交给业务代码前,以及错误发生时接管处理逻辑。
最小示例
ts
import lsData from '@loongship-kit/data';
const client = lsData.create({
hooks: {
async onRequest(context) {
return {
...context,
requestOptions: {
...context.requestOptions,
headers: {
...context.requestOptions.headers,
'X-Trace-Id': crypto.randomUUID()
}
}
};
},
async onResponse(context) {
return context;
},
async onError(context) {
if (context.kind === 'business') {
console.warn('业务错误:', context.error.code, context.error.message);
} else {
console.error('请求失败:', context.error);
}
return { action: 'throw' };
}
}
});触发时机
onRequest在 SDK 完成默认配置合并前触发。适合动态补充请求头、超时、参数等。onResponse在 SDK 返回结果交给业务代码前触发。拿到的是 SDK 统一响应结构,适合统一改写返回内容。onError在 SDK 判定为业务错误,或者请求没有拿到可用业务响应时触发。可通过context.kind区分business和transport。
默认配置和 onRequest 的分工
- 默认配置 适合放稳定不变的值,比如
key、baseURL、统一超时、固定请求头。 onRequest适合放每次调用都可能变化的逻辑,比如 traceId、临时鉴权参数、按接口动态改超时。
可以把它理解成:
text
client defaults -> onRequest -> final requestonRequest
onRequest 可以直接改写参数和单次请求选项。
ts
const client = lsData.create({
hooks: {
async onRequest(context) {
return {
...context,
params: {
...context.params,
tenantId: 'demo'
},
requestOptions: {
...context.requestOptions,
timeout: 30000
}
};
}
}
});这个 hook 只作用于当前 client。
onResponse
onResponse 拿到的是 SDK 统一响应结构,因此你可以直接改写最终返回值。
ts
const client = lsData.create({
hooks: {
async onResponse(context) {
if (Array.isArray(context.response.data)) {
return {
...context,
response: {
...context.response,
data: context.response.data.slice(0, 20)
}
};
}
return context;
}
}
});onError
默认情况下,SDK 会抛出 LoongshipApiError。
如果你想改成兜底返回,也可以在 onError 里处理:
ts
const client = lsData.create({
hooks: {
async onError(context) {
if (context.kind === 'business' && context.error.code === 29) {
return {
action: 'return',
response: {
code: 0,
data: []
}
};
}
return { action: 'throw' };
}
}
});传输错误适合统一日志、埋点,或者按业务需要转成兜底结果:
ts
const client = lsData.create({
hooks: {
async onError(context) {
if (context.kind !== 'transport') {
return { action: 'throw' };
}
console.error('transport error:', context.error);
return {
action: 'return',
response: {
code: 10000,
data: []
}
};
}
}
});如果你不想拦截,直接返回:
ts
{ action: 'throw' }这时 SDK 会继续抛出原始错误。