Skip to content

Latest commit

 

History

History
150 lines (121 loc) · 4.15 KB

06-method-metadata.md

File metadata and controls

150 lines (121 loc) · 4.15 KB
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.

Use metadata to identify identities

Use identity before request

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:

  1. Information is not aggregated with method instances, making maintainability even worse;
  2. 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 = '...';
    }
  }
});

Use the identity after the response

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
     }
   }
});

Use metadata to pass information

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;
    }
  }
});

Tips for non-typescript projects

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.