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 也可以配置适配器,针对某个特定接口单独处理。
|
||||
//
|
||||
// requestAdaptor(api) {
|
||||
// // 支持异步,可以通过 api.mockResponse 来设置返回结果,跳过真正的请求发送
|
||||
// // 此功能自定义 fetcher 的话会失效
|
||||
// return api;
|
||||
// }
|
||||
//
|
||||
|
@ -659,6 +659,7 @@ const schema = {
|
||||
url: '/api/mock2/form/saveForm',
|
||||
requestAdaptor: function (api, context) {
|
||||
console.log(context); // 打印上下文数据
|
||||
|
||||
return {
|
||||
...api,
|
||||
data: {
|
||||
@ -687,6 +688,47 @@ const schema = {
|
||||
|
||||
你也可以使用`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`实现接收适配器
|
||||
|
@ -51,12 +51,12 @@ export function embed(
|
||||
container.classList.add('amis-scope');
|
||||
let scoped = {};
|
||||
|
||||
const requestAdaptor = (config: any) => {
|
||||
const requestAdaptor = async (config: any) => {
|
||||
const fn =
|
||||
env && typeof env.requestAdaptor === 'function'
|
||||
? env.requestAdaptor.bind()
|
||||
: (config: any) => config;
|
||||
const request = fn(config) || config;
|
||||
: async (config: any) => config;
|
||||
const request = (await fn(config)) || config;
|
||||
|
||||
return request;
|
||||
};
|
||||
@ -189,7 +189,7 @@ export function embed(
|
||||
config.method = method;
|
||||
config.data = data;
|
||||
|
||||
config = requestAdaptor(config);
|
||||
config = await requestAdaptor(config);
|
||||
|
||||
if (method === 'get' && data) {
|
||||
config.params = data;
|
||||
@ -210,7 +210,9 @@ export function embed(
|
||||
return true;
|
||||
};
|
||||
|
||||
let response = await axios(config);
|
||||
let response = config.mockResponse
|
||||
? config.mockResponse
|
||||
: await axios(config);
|
||||
response = await attachmentAdpator(response, __);
|
||||
response = responseAdaptor(api)(response);
|
||||
|
||||
|
@ -217,6 +217,7 @@ export interface ApiObject extends BaseApiObject {
|
||||
operationName?: string;
|
||||
body?: PlainObject;
|
||||
query?: PlainObject;
|
||||
mockResponse?: PlainObject;
|
||||
adaptor?: (
|
||||
payload: object,
|
||||
response: fetcherResult,
|
||||
|
@ -505,6 +505,12 @@ export function wrapFetcher(
|
||||
api.headers['Content-Type'] = 'application/json';
|
||||
}
|
||||
|
||||
// 如果发送适配器中设置了 mockResponse
|
||||
// 则直接跳过请求发送
|
||||
if (api.mockResponse) {
|
||||
return wrapAdaptor(Promise.resolve(api.mockResponse) as any, api, data);
|
||||
}
|
||||
|
||||
if (!isValidApi(api.url)) {
|
||||
throw new Error(`invalid api url:${api.url}`);
|
||||
}
|
||||
|
@ -359,7 +359,7 @@ test('api:isvalidapi', () => {
|
||||
).toBeTruthy();
|
||||
});
|
||||
|
||||
test('api:requestAdaptor', async () => {
|
||||
test('api:requestAdaptor1', async () => {
|
||||
const notify = jest.fn();
|
||||
const fetcher = jest.fn().mockImplementation(() =>
|
||||
Promise.resolve({
|
||||
@ -429,3 +429,83 @@ test('api:requestAdaptor', async () => {
|
||||
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