mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-29 18:48:45 +08:00
feat: api 的 requestAdaptor 支持拦截请求 (#7566)
This commit is contained in:
parent
4f07627051
commit
73a78a1406
@ -155,6 +155,8 @@ let amisScoped = amis.embed(
|
|||||||
// 另外在 amis 配置项中的 api 也可以配置适配器,针对某个特定接口单独处理。
|
// 另外在 amis 配置项中的 api 也可以配置适配器,针对某个特定接口单独处理。
|
||||||
//
|
//
|
||||||
// requestAdaptor(api) {
|
// requestAdaptor(api) {
|
||||||
|
// // 支持异步,可以通过 api.mockResponse 来设置返回结果,跳过真正的请求发送
|
||||||
|
// // 此功能自定义 fetcher 的话会失效
|
||||||
// return api;
|
// return api;
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
|
@ -659,6 +659,7 @@ const schema = {
|
|||||||
url: '/api/mock2/form/saveForm',
|
url: '/api/mock2/form/saveForm',
|
||||||
requestAdaptor: function (api, context) {
|
requestAdaptor: function (api, context) {
|
||||||
console.log(context); // 打印上下文数据
|
console.log(context); // 打印上下文数据
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...api,
|
...api,
|
||||||
data: {
|
data: {
|
||||||
@ -687,6 +688,47 @@ const schema = {
|
|||||||
|
|
||||||
你也可以使用`debugger`自行进行调试。
|
你也可以使用`debugger`自行进行调试。
|
||||||
|
|
||||||
|
#### 拦截请求
|
||||||
|
|
||||||
|
如果 api 发送适配器中,修改 api 对象,在 api 对象里面放入 `mockReponse` 属性,则会拦截请求发送,amis 内部会直接使用 `mockReponse` 的结果返回。
|
||||||
|
|
||||||
|
```js
|
||||||
|
const schema = {
|
||||||
|
type: 'form',
|
||||||
|
api: {
|
||||||
|
method: 'post',
|
||||||
|
url: '/api/mock2/form/saveForm',
|
||||||
|
requestAdaptor: function (api, context) {
|
||||||
|
return {
|
||||||
|
// 模拟 http 请求返回
|
||||||
|
mockResponse: {
|
||||||
|
status: 200, // http 返回状态
|
||||||
|
data: {
|
||||||
|
// http 返回结果
|
||||||
|
status: 0, // amis 返回数据的状态
|
||||||
|
data: {
|
||||||
|
name: '模拟返回的值'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'input-text',
|
||||||
|
name: 'name',
|
||||||
|
label: '姓名:'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'text',
|
||||||
|
type: 'input-email',
|
||||||
|
label: '邮箱:'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
### 配置接收适配器
|
### 配置接收适配器
|
||||||
|
|
||||||
同样的,如果后端返回的响应结构不符合 amis 的[接口格式要求](#%E6%8E%A5%E5%8F%A3%E8%BF%94%E5%9B%9E%E6%A0%BC%E5%BC%8F-%E9%87%8D%E8%A6%81-),而后端不方便调整时,可以配置`adaptor`实现接收适配器
|
同样的,如果后端返回的响应结构不符合 amis 的[接口格式要求](#%E6%8E%A5%E5%8F%A3%E8%BF%94%E5%9B%9E%E6%A0%BC%E5%BC%8F-%E9%87%8D%E8%A6%81-),而后端不方便调整时,可以配置`adaptor`实现接收适配器
|
||||||
|
@ -51,12 +51,12 @@ export function embed(
|
|||||||
container.classList.add('amis-scope');
|
container.classList.add('amis-scope');
|
||||||
let scoped = {};
|
let scoped = {};
|
||||||
|
|
||||||
const requestAdaptor = (config: any) => {
|
const requestAdaptor = async (config: any) => {
|
||||||
const fn =
|
const fn =
|
||||||
env && typeof env.requestAdaptor === 'function'
|
env && typeof env.requestAdaptor === 'function'
|
||||||
? env.requestAdaptor.bind()
|
? env.requestAdaptor.bind()
|
||||||
: (config: any) => config;
|
: async (config: any) => config;
|
||||||
const request = fn(config) || config;
|
const request = (await fn(config)) || config;
|
||||||
|
|
||||||
return request;
|
return request;
|
||||||
};
|
};
|
||||||
@ -189,7 +189,7 @@ export function embed(
|
|||||||
config.method = method;
|
config.method = method;
|
||||||
config.data = data;
|
config.data = data;
|
||||||
|
|
||||||
config = requestAdaptor(config);
|
config = await requestAdaptor(config);
|
||||||
|
|
||||||
if (method === 'get' && data) {
|
if (method === 'get' && data) {
|
||||||
config.params = data;
|
config.params = data;
|
||||||
@ -210,7 +210,9 @@ export function embed(
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
let response = await axios(config);
|
let response = config.mockResponse
|
||||||
|
? config.mockResponse
|
||||||
|
: await axios(config);
|
||||||
response = await attachmentAdpator(response, __);
|
response = await attachmentAdpator(response, __);
|
||||||
response = responseAdaptor(api)(response);
|
response = responseAdaptor(api)(response);
|
||||||
|
|
||||||
|
@ -217,6 +217,7 @@ export interface ApiObject extends BaseApiObject {
|
|||||||
operationName?: string;
|
operationName?: string;
|
||||||
body?: PlainObject;
|
body?: PlainObject;
|
||||||
query?: PlainObject;
|
query?: PlainObject;
|
||||||
|
mockResponse?: PlainObject;
|
||||||
adaptor?: (
|
adaptor?: (
|
||||||
payload: object,
|
payload: object,
|
||||||
response: fetcherResult,
|
response: fetcherResult,
|
||||||
|
@ -505,6 +505,12 @@ export function wrapFetcher(
|
|||||||
api.headers['Content-Type'] = 'application/json';
|
api.headers['Content-Type'] = 'application/json';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 如果发送适配器中设置了 mockResponse
|
||||||
|
// 则直接跳过请求发送
|
||||||
|
if (api.mockResponse) {
|
||||||
|
return wrapAdaptor(Promise.resolve(api.mockResponse) as any, api, data);
|
||||||
|
}
|
||||||
|
|
||||||
if (!isValidApi(api.url)) {
|
if (!isValidApi(api.url)) {
|
||||||
throw new Error(`invalid api url:${api.url}`);
|
throw new Error(`invalid api url:${api.url}`);
|
||||||
}
|
}
|
||||||
|
@ -359,7 +359,7 @@ test('api:isvalidapi', () => {
|
|||||||
).toBeTruthy();
|
).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('api:requestAdaptor', async () => {
|
test('api:requestAdaptor1', async () => {
|
||||||
const notify = jest.fn();
|
const notify = jest.fn();
|
||||||
const fetcher = jest.fn().mockImplementation(() =>
|
const fetcher = jest.fn().mockImplementation(() =>
|
||||||
Promise.resolve({
|
Promise.resolve({
|
||||||
@ -429,3 +429,83 @@ test('api:requestAdaptor', async () => {
|
|||||||
email: 'appended@test.com'
|
email: 'appended@test.com'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('api:requestAdaptor2', async () => {
|
||||||
|
const notify = jest.fn();
|
||||||
|
const fetcher = jest.fn().mockImplementation(() =>
|
||||||
|
Promise.resolve({
|
||||||
|
data: {
|
||||||
|
status: 0,
|
||||||
|
msg: 'ok',
|
||||||
|
data: {
|
||||||
|
id: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
const requestAdaptor = jest.fn().mockImplementation(api => {
|
||||||
|
return Promise.resolve({
|
||||||
|
...api,
|
||||||
|
mockResponse: {
|
||||||
|
status: 200,
|
||||||
|
data: {
|
||||||
|
status: 0,
|
||||||
|
msg: 'ok',
|
||||||
|
data: {
|
||||||
|
id: 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const {container, getByText} = render(
|
||||||
|
amisRender(
|
||||||
|
{
|
||||||
|
type: 'page',
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'form',
|
||||||
|
id: 'form_submit',
|
||||||
|
submitText: '提交表单',
|
||||||
|
api: {
|
||||||
|
method: 'post',
|
||||||
|
url: '/api/mock2/form/saveForm',
|
||||||
|
requestAdaptor: requestAdaptor
|
||||||
|
},
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'input-text',
|
||||||
|
name: 'id',
|
||||||
|
label: 'Id'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input-text',
|
||||||
|
name: 'name',
|
||||||
|
label: '姓名:',
|
||||||
|
value: 'fex'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
makeEnv({
|
||||||
|
notify,
|
||||||
|
fetcher
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(getByText('提交表单')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
fireEvent.click(getByText(/提交表单/));
|
||||||
|
await wait(300);
|
||||||
|
|
||||||
|
expect(requestAdaptor).toHaveBeenCalled();
|
||||||
|
expect(fetcher).toHaveBeenCalledTimes(0);
|
||||||
|
expect(container.querySelector('input[name="id"]')).toBeInTheDocument();
|
||||||
|
expect((container.querySelector('input[name="id"]') as any).value).toBe('2');
|
||||||
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user