title |
---|
Method Metadata |
Method instances run through the entire request life cycle of alova, and there will be a large number of different method instances in the project. Sometimes we need to add additional information to specific method instances to facilitate their identification or additional information transfer. Wait, at this point, we need to use method metadata.
For example, most of the interfaces in your project need to be accompanied by token
for each request, but there are still some interfaces that do not require verification. You may handle them uniformly in the global beforeRequest
function.
const nonvalidateRequiredApi = [
'/api/url1',
'/api/url2',
'/api/url3'
// ...
];
createAlova({
beforeRequest(method) {
if (!nonvalidateRequiredApi.includes(method.url)) {
method.config.headers.token = '...';
}
}
});
This will cause the following two problems:
- Information is not aggregated with method instances, making maintainability even worse;
- Coding is more troublesome;
To solve these two problems, we will use metadata to identify a specific method instance when it is created.
Step 1: Define metadata when creating method instance
const loginAPI = (username, password) => {
const methodInstance = alovaInst.Post('/login', {
username,
password
});
methodInstance.meta = {
ignoreToken: true
};
return methodInstance;
};
And you can also directly define metadata in config
const loginAPI = (username, password) => {
return alovaInst.Post(
'/login',
{
username,
password
},
{
meta: {
ignoreToken: true
}
}
);
};
Step 2: Use metadata as the basis for judgment in beforeRequest
createAlova({
// ...
beforeRequest(method) {
if (!method.meta?.ignoreToken) {
method.config.headers.token = '...';
}
}
});
This method can also be used in global responded
. For example, in most cases, the request api will return json data, but there may be a file download interface, which will return a binary data stream. In this case Below, you can use different metadata in responded
to handle different responses separately.
Step one: When creating a method instance, you also need to assign a metadata
const downloadAPI = filePath => {
const methodInstance = alovaInst.Post('/download_file', {
filePath
});
methodInstance.meta = {
isDownload: true
};
return methodInstance;
};
Step 2: Use metadata in responded
as a basis for judgment
createAlova({
// ...
responded:
onSuccess: (response, method) => method.meta?.isDownload ? response.blob() : response.json()
onError: (error, method) => {
//Metadata of method instances can also be accessed when responding to errors
}
}
});
In some cases, if you want to add additional information to different method instances for use elsewhere, you can also use metadata to save it. Take uniformly generating different method instance IDs as an example.
createAlova({
beforeRequest(method) {
if (!method.meta.generateId) {
method.meta.uid = generateUUID();
}
},
responded: {
onSuccess(response, method) {
// Access the meta data generated by the current method when the request is successful.
const currentMethodUID = method.meta.uid;
},
onError(error, method) {
//Access the meta data generated by the current method when the request fails.
const currentMethodUID = method.meta.uid;
}
}
});
In a non-typescript environment, you can use any attribute as an information carrier, not limited to the meta
attribute.
methodInstance.showResponseMsg = true;
methodInstance.others = 'abc';
Only in the typescript environment, any attribute name will report that the attribute "$0" does not exist. ts(2339), so in the type we specify the
meta` attribute as the information carrier.