添加接口数据返回映射

This commit is contained in:
2betop 2021-01-13 13:00:38 +08:00
parent 7949587420
commit 1b16c4c6a3
4 changed files with 78 additions and 12 deletions

View File

@ -412,6 +412,45 @@ API 还支持配置对象类型
这下我们再打开网络面板,发现只有一条请求了
### 配置返回数据
如果接口返回的数据结构不符合预期,可以通过配置 `responseData`来修改,同样支持[数据映射](../concepts/data-mapping),可用来映射的数据为接口的实际数据(接口返回的 `data` 部分),额外加 `api` 变量。其中 `api.query` 为接口发送的 query 参数,`api.body` 为接口发送的内容体原始数据。
```json
{
"type": "page",
"initApi": {
"method": "get",
"url": "/api/xxx",
"responseData": {
"&": "$$",
"first": "${items|first}"
}
}
}
```
假如接口实际返回为:
```json
{
"status": 0,
"msg": "",
"data": {
"items": [{"a": 1}, {"a": 2}]
}
}
```
经过映射,给组件的数据为:
```json
{
"items": [{"a": 1}, {"a": 2}],
"first": {"a": 1}
}
```
### 配置请求适配器
amis 的 API 配置,如果无法配置出你想要的请求结构,那么可以配置`requestAdaptor`发送适配器

View File

@ -237,6 +237,13 @@ export interface SchemaApiObject {
[propName: string]: any;
};
/**
*
*/
responseData?: {
[propName: string]: any;
};
/**
* method get data
* data query

View File

@ -5,6 +5,8 @@ export interface ApiObject extends SchemaApiObject {
withCredentials?: boolean;
cancelExecutor?: (cancel: Function) => void;
};
body?: PlainObject;
query?: PlainObject;
adaptor?: (payload: object, response: fetcherResult, api: ApiObject) => any;
requestAdaptor?: (api: ApiObject) => ApiObject;
}

View File

@ -9,7 +9,8 @@ import {
hasFile,
object2formData,
qsstringify,
cloneObject
cloneObject,
createObject
} from './helper';
const rSchema = /(?:^|raw\:)(get|post|put|delete|patch|options|head):/i;
@ -76,7 +77,7 @@ export function buildApi(
);
api.url =
tokenize(api.url.substring(0, idx + 1), data, '| url_encode') +
qsstringify(dataMapping(params, data)) +
qsstringify((api.query = dataMapping(params, data))) +
(~hashIdx ? api.url.substring(hashIdx) : '');
} else {
api.url = tokenize(api.url, data, '| url_encode');
@ -87,15 +88,15 @@ export function buildApi(
}
if (api.data) {
api.data = dataMapping(api.data, data);
api.body = api.data = dataMapping(api.data, data);
} else if (api.method === 'post' || api.method === 'put') {
api.data = cloneObject(data);
api.body = api.data = cloneObject(data);
}
// get 类请求,把 data 附带到 url 上。
if (api.method === 'get') {
if (!~raw.indexOf('$') && !api.data && autoAppend) {
api.data = data;
api.query = api.data = data;
} else if (
api.attachDataToQuery === false &&
api.data &&
@ -104,12 +105,13 @@ export function buildApi(
) {
const idx = api.url.indexOf('?');
if (~idx) {
let params = {
let params = (api.query = {
...qs.parse(api.url.substring(idx + 1)),
...data
};
});
api.url = api.url.substring(0, idx) + '?' + qsstringify(params);
} else {
api.query = data;
api.url += '?' + qsstringify(data);
}
}
@ -117,12 +119,13 @@ export function buildApi(
if (api.data && api.attachDataToQuery !== false) {
const idx = api.url.indexOf('?');
if (~idx) {
let params = {
let params = (api.query = {
...qs.parse(api.url.substring(idx + 1)),
...api.data
};
});
api.url = api.url.substring(0, idx) + '?' + qsstringify(params);
} else {
api.query = api.data;
api.url += '?' + qsstringify(api.data);
}
delete api.data;
@ -162,7 +165,7 @@ function str2function(
}
}
function responseAdaptor(ret: fetcherResult) {
function responseAdaptor(ret: fetcherResult, api: ApiObject) {
const data = ret.data;
let hasStatusField = true;
@ -184,6 +187,21 @@ function responseAdaptor(ret: fetcherResult) {
payload.errors = data.errors;
}
if (payload.ok && api.responseData) {
payload.data = dataMapping(
api.responseData,
createObject(
{api},
(Array.isArray(payload.data)
? {
items: payload.data
}
: payload.data) || {}
)
);
}
return payload;
}
@ -244,8 +262,8 @@ export function wrapAdaptor(promise: Promise<fetcherResult>, api: ApiObject) {
data: result
};
})
.then(responseAdaptor)
: promise.then(responseAdaptor);
.then(ret => responseAdaptor(ret, api))
: promise.then(ret => responseAdaptor(ret, api));
}
export function isApiOutdated(