Skip to content

Commit

Permalink
perf: easy to define fieldName of response data (#5442)
Browse files Browse the repository at this point in the history
  • Loading branch information
mynetfan authored Jan 20, 2025
1 parent 5611f6c commit 22e6f28
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 46 deletions.
10 changes: 10 additions & 0 deletions apps/web-antd/src/api/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { useAppConfig } from '@vben/hooks';
import { preferences } from '@vben/preferences';
import {
authenticateResponseInterceptor,
defaultResponseInterceptor,
errorMessageResponseInterceptor,
RequestClient,
} from '@vben/request';
Expand Down Expand Up @@ -70,6 +71,15 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
},
});

// 处理返回的响应数据格式
client.addResponseInterceptor(
defaultResponseInterceptor({
codeField: 'code',
dataField: 'data',
successCode: 0,
}),
);

// token过期的处理
client.addResponseInterceptor(
authenticateResponseInterceptor({
Expand Down
10 changes: 10 additions & 0 deletions apps/web-ele/src/api/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { useAppConfig } from '@vben/hooks';
import { preferences } from '@vben/preferences';
import {
authenticateResponseInterceptor,
defaultResponseInterceptor,
errorMessageResponseInterceptor,
RequestClient,
} from '@vben/request';
Expand Down Expand Up @@ -70,6 +71,15 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
},
});

// 处理返回的响应数据格式
client.addResponseInterceptor(
defaultResponseInterceptor({
codeField: 'code',
dataField: 'data',
successCode: 0,
}),
);

// token过期的处理
client.addResponseInterceptor(
authenticateResponseInterceptor({
Expand Down
10 changes: 10 additions & 0 deletions apps/web-naive/src/api/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { useAppConfig } from '@vben/hooks';
import { preferences } from '@vben/preferences';
import {
authenticateResponseInterceptor,
defaultResponseInterceptor,
errorMessageResponseInterceptor,
RequestClient,
} from '@vben/request';
Expand Down Expand Up @@ -69,6 +70,15 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
},
});

// 处理返回的响应数据格式
client.addResponseInterceptor(
defaultResponseInterceptor({
codeField: 'code',
dataField: 'data',
successCode: 0,
}),
);

// token过期的处理
client.addResponseInterceptor(
authenticateResponseInterceptor({
Expand Down
39 changes: 39 additions & 0 deletions packages/effects/request/src/request-client/preset-interceptors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,48 @@ import type { RequestClient } from './request-client';
import type { MakeErrorMessageFn, ResponseInterceptorConfig } from './types';

import { $t } from '@vben/locales';
import { isFunction } from '@vben/utils';

import axios from 'axios';

export const defaultResponseInterceptor = ({
codeField = 'code',
dataField = 'data',
successCode = 0,
}: {
/** 响应数据中代表访问结果的字段名 */
codeField: string;
/** 响应数据中装载实际数据的字段名,或者提供一个函数从响应数据中解析需要返回的数据 */
dataField: ((response: any) => any) | string;
/** 当codeField所指定的字段值与successCode相同时,代表接口访问成功。如果提供一个函数,则返回true代表接口访问成功 */
successCode: ((code: any) => boolean) | number | string;
}): ResponseInterceptorConfig => {
return {
fulfilled: (response) => {
const { config, data: responseData, status } = response;

if (config.responseReturn === 'raw') {
return response;
}
const code = responseData[codeField];
if (
status >= 200 && status < 400 && isFunction(successCode)
? successCode(code)
: code === successCode
) {
if (config.responseReturn === 'body') {
return responseData;
} else {
return isFunction(dataField)
? dataField(responseData)
: responseData[dataField];
}
}
throw Object.assign({}, response, { response });
},
};
};

export const authenticateResponseInterceptor = ({
client,
doReAuthenticate,
Expand Down
23 changes: 0 additions & 23 deletions packages/effects/request/src/request-client/request-client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,29 +48,6 @@ describe('requestClient', () => {
expect(response.data).toEqual(mockData);
});

it('should return different response types', async () => {
const mockData = { code: 0, msg: 'ok', data: 'response' };
mock.onGet('/test/diff').reply(200, mockData);

const responseRaw = await requestClient.get('/test/diff', {
responseReturn: 'raw',
});
expect(responseRaw.status).toBe(200);
expect(responseRaw.data).toEqual(mockData);

const responseBody = await requestClient.get('/test/diff', {
responseReturn: 'body',
});
expect(responseBody.code).toEqual(mockData.code);
expect(responseBody.msg).toEqual(mockData.msg);
expect(responseBody.data).toEqual(mockData.data);

const responseData = await requestClient.get('/test/diff', {
responseReturn: 'data',
});
expect(responseData).toEqual(mockData.data);
});

it('should handle network errors', async () => {
mock.onGet('/test/error').networkError();
try {
Expand Down
24 changes: 1 addition & 23 deletions packages/effects/request/src/request-client/request-client.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import type { AxiosInstance, AxiosResponse } from 'axios';

import type {
HttpResponse,
RequestClientConfig,
RequestClientOptions,
} from './types';
import type { RequestClientConfig, RequestClientOptions } from './types';

import { bindMethods, merge } from '@vben/utils';

Expand Down Expand Up @@ -54,24 +50,6 @@ class RequestClient {
this.addResponseInterceptor =
interceptorManager.addResponseInterceptor.bind(interceptorManager);

// 添加基础的响应处理,根据设置决定返回响应的哪一部分
this.addResponseInterceptor<HttpResponse>({
fulfilled: (response) => {
const { config, data: responseData, status } = response;

if (config.responseReturn === 'raw') {
return response;
}

const { code, data } = responseData;

if (status >= 200 && status < 400 && code === 0) {
return config.responseReturn === 'body' ? responseData : data;
}
throw Object.assign({}, response, { response });
},
});

// 实例化文件上传器
const fileUploader = new FileUploader(this);
this.upload = fileUploader.upload.bind(fileUploader);
Expand Down
10 changes: 10 additions & 0 deletions playground/src/api/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { useAppConfig } from '@vben/hooks';
import { preferences } from '@vben/preferences';
import {
authenticateResponseInterceptor,
defaultResponseInterceptor,
errorMessageResponseInterceptor,
RequestClient,
} from '@vben/request';
Expand Down Expand Up @@ -70,6 +71,15 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
},
});

// 处理返回的响应数据格式
client.addResponseInterceptor(
defaultResponseInterceptor({
codeField: 'code',
dataField: 'data',
successCode: 0,
}),
);

// token过期的处理
client.addResponseInterceptor(
authenticateResponseInterceptor({
Expand Down

0 comments on commit 22e6f28

Please sign in to comment.