(45) Organize and Act (1895) Organize and invoke API calls in Nuxt.js by using the Nuxt plug-in and the overall abstraction of restful API calls. And the interface calls are really quite clear. When I first saw the API organization abstraction based on the repository pattern, it was a real light bulb moment. It’s also because I haven’t really worked with restful style interfaces in the real world. In short, elegant.

In short, we don’t have restful apis, nor do we enjoy that “elegance”, but the general idea is still worth learning from. The problems to be solved are much the same as with axiOS normally, such as organizing all the interface definitions together for easy management; For example, setting up a global interceptor to do some global logic processing and error handling before the request is actually sent and at the beginning of the response. Such as giving default baseURL, timeout, request header fields…

First, create a factory function

Make sure you have the necessary dependencies installed before doing this: NPM i-s@nuxtjs /axios. Since we don’t have to worry about restful issues, GET and POST already meet our needs. So there is code like this:

// assets/js/apifactory.js

/** * factory function * @param $axios Axios instance * @param {String} API * @param {Object} config Optional additional configuration, * @param data post body */ 
export default $axios => (api, config) = > ({
  get() {
    return $axios.$get(api, config);
  },
  post(data) {
    return$axios.$post(api, data, config); }});Copy the code

So once you have that, you have to think about how do you pass in an axios instance

Next, create a Nuxt Plugin

We’ll call it apiRepository and have the following code:

// plugins/apirepository.js

import apiFactory from '~/assets/js/apifactory';

export default ({ $axios }, inject) => {

  const requestWithAxios = apiFactory($axios);

  const apiRepository = {};

  inject('apiRepository', apiRepository);
}

Copy the code

But how does this plug-in fit into the actual interface?

When we pass $axios and execute the apiFactory, we get another factory function, requestWithAxios, for which we need to pass the API and config to produce the object literal that contains the GET and POST methods. That’s how we’re going to implement the interface call. How to do?

Create a unified directory for your apis

Continue with the factory function and create a new file, apiRepository /user.js:

export default (request, baseURL) => {
  const msgConf = { // Do some extra configuration
    headers: { 'Content-Type': 'application/json',},timeout: 30000,}return {
    index: request(`${baseURL}/user/index`),
    message: request(`${baseURL}/user/msg`, msgConf),
    // ...}}Copy the code

Like above, we will deposit the same functional areas of the interface to a file, returns an object, exposed to the plugins/apirepository js:

import userApi from '~/apirepository/user';
// ...

const demoEnv = process.env.DEMO_ENV;
const baseURL = hjxyEnv === 'dev' ? '/api' : 'https://api.xxxx.com';

export default ({ $axios }, inject) => {

  $axios.defaults.timeout = 20000;

  $axios.onRequest(config= > {
    // ...
  });

  $axios.onResponse(response= > {
    // ...
  });

  $axios.onError(err= > {
    // ...
  });

  // List of global injection apis
  const requestWithAxios = apiFactory($axios);
  const apiRepository = {
    user: userApi(requestWithAxios, baseURL),
    // ...

  }

  inject('apiRepository', apiRepository);
}

Copy the code

At this point, we’re done, and the injected apiRepository can be called anywhere in the entire project. But don’t forget, there’s more

Configure the plug-in in nuxt.config.js

We configure it into nuxt.config.js and, by the way, proxy to solve the local cross-domain problem:

// nuxt.config.js
module.exports = {
  // ...

  plugins: [
    '~/plugins/apirepository.js',].modules: [
    '@nuxtjs/axios'.'@nuxtjs/proxy'.// The latest documentation shows that manual registration is no longer required, but dependencies still need to be installed].axios: {
    proxy: true.https: process.env.DEMO_ENV === 'prod',},proxy: {
    '/api': {
      target: 'https://api.xxx.com/'.pathRewrite: {
        '^/api' : '/',}}},// ...

}

Copy the code

Finally, I can tune the interface

For calls in asyncData and FETCH methods:

export default {
  async asyncData({ app }) {
    try {
      const res = app.$apiRepository.home.index.get();
      // ...
      return { ...res.data };
    }catch(err) {}
  },
}

Copy the code

And when the need in a single page components or store called, is this. $apiRepository. Home. The index. The get (); .

The last

According to the actual situation of the project, we need to add some special processing logic to the three interceptors onRequest, onResponse and onError to make them globally scoped. In the case of request interceptors, we can uniformly add public parameters like tokens; Screening request data to prevent minor harassment such as SQL injection; And since content-Type is the default Application/X-www-form-urlencoded format, don’t forget to serialize the request parameters consistently:

import { SQLInjectionDefence } from '~/assets/js/utils';
import qs from 'qs';

// ...

export default ({ $axios }, inject) => {

  $axios.onRequest(config= > {
    // ...
    const token = store.getters.token;
    if(config.data === void 0 && token) {
      config.data = { token };
    }else if(token) {
      config.data.token = token;
    }
    config.data = qs.stringify(SQLInjectionDefence(config.data));

    // ...

  });

  // ...

}

Copy the code

In short, open your imagination and do more globally applicable logic in order to simplify your code. For more details on the use of @nuxtjs/ Axios, see the official documentation.

In fact, Nuxt’s plug-in mechanism has many advantages, and many practical development problems can be solved by it, such as how to make statistics code work in Nuxt applications, how to inject third party plug-ins, etc. The following article makes a brief introduction ~