Encapsulation of axios and Management of API Interface in React Project

  • 2021-11-23 22:19:47
  • OfStack

Preface to the table of contents Installation Introduce Switching of environment Request interception Response interception Unified 1 management of api Summarize

Preface

In the react project, we usually use axios library for interacting with the background to obtain data, which is http library based on promise and can run in browser and node. js. It has many excellent features, such as intercepting requests and responses, canceling requests, transforming json, client defense XSRF and so on. If you still don't know axios, you can go to axios documentation.

Installation


// Use npm Installation 
npm install axios; 
// Use yarn Installation 
yarn add axios

Introduce

In the project root directory, create a new request folder, and then create a new index. js and a new api. js file inside. The index. js file is used to encapsulate our axios, and api. js is used to manage our interfaces.


// In index.js Introduce in axios
import axios from 'axios';
// Introduce qs Module to serialize post Data of type 
import QS from 'qs';
//antd Adj. message Prompt component, everyone can according to their own ui Component changes. 
import { message } from 'antd'

Switching of environment

Our project environment may include development environment, test environment and production environment. We match our default interface url prefix with the node environment variable. The global variable for node, process, process.env.NODE_ENV, is required here to distinguish between development and production environments.


// Save environment variables 
const isPrd = process.env.NODE_ENV == 'production';

// Distinguish between development environment and production environment URL
export const basciUrl = isPrd ? 'https://www.production.com' : 'http://www.development.com'

The purpose of exporting the basic URL here is to prevent resources from being used in other places. It is necessary to distinguish between production environment and development environment, and the import can be used directly.

Request interception

We can intercept a request before sending it. Why do we intercept it? What do we intercept the request for? For example, some requests require the user to log in before they can be accessed, or when post requests, we need to serialize the data we submit. At this time, we can intercept the request before it is sent, so that we can do what we want.


// Settings axios Base path 
const service = axios.create({
  baseURL: basicUrl
})
//  Request interceptor 
service.interceptors.request.use(config => { 
  //  Does it exist in the local store before each request is sent token , can also be passed through Redux Here, we only demonstrate getting it locally token
  //  If it exists, it will be unified 1 In http Requested header Add them all token , so that the background is based on token Judge your login status 
  //  Even if it exists locally token , it is also possible token Is expired, so the return status should be judged in the response interceptor  
  const token = window.localStorage.getItem('userToken') || window.sessionStorage.getItem('userToken');
  // Add in each request token
  config.data = Object.assign({}, config.data, {
    token: token,
  })
  // Set the request header 
  config.headers = {
    'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'
  }
  config.data = QS.stringify(config.data)
  return config
}, error => { 
    return error;
})

It is said here that token is stored locally through localStorage or sessionStorage after login is completed, and then every time the user enters the page (i.e., in main. js), it will first read token from the local storage. If token exists, it means that the user has logged in, then update token status in Redux. Then, every time you request an interface, you will carry token in the requested header, and the background personnel can judge whether your login has expired according to the token you carry. If you don't carry it, you have not logged in.

Response interception


//  Response interceptor 
service.interceptors.response.use(response => {
  // Do different things according to the different status codes returned 
  //  Here 1 Be sure to negotiate with the back-office developers 1 Error status code of 
  if (response.code) {
    switch (response.code) {
      case 200:
        return response.data;
      case 401:
        // Handling method not logged in 
        break;
      case 403:
        //token Expired processing method 
        break;
      default:
        message.error(response.data.msg)
    }
  } else { 
    return response;
  }
})
// Finally, put the packaged axios Export 
export default service

The response interceptor is easy to understand, that is, the data returned to us by the server, and we can process it before we get it. For example, the above idea: If the status code returned by the background is 200, the data will be returned normally; Otherwise, we will make some errors according to the type of error status code, and the specific return status code needs to deal with those processes and need to negotiate with the background developer.

The above message. error () method when I introduced the antd library prompt component, need according to your UI library, corresponding use prompt component

Unified 1 management of api

A neat api is like a circuit board 1, which can clear the whole circuit even if it is complicated. As mentioned above, we will create a new api. js, and then store all our api interfaces in this file.

First we introduce our encapsulated axios in api. js


// Import our encapsulated axios 
import service from './index'

Now, for example, we have an interface like this, which is an post request:


http://www.development.com/api/v1/articleEdit

We can encapsulate this in api. js:


export const apiArticleEdit = info => service.post('/api/v1/articleEdit', info);

We defined an apiArticleEdit method with a parameter info, and info is the parameter object we carry when we request the interface. Then we call our encapsulated axios method. The first parameter is our interface address, and the second parameter is the info parameter of apiArticleEdit, that is, the parameter object carried when requesting the interface. Finally, apiArticleEdit is derived from export.

Then we can call our api interface in our page as follows:


import React, { Component } from 'react'
 import { apiArticleEdit } from './request/api'
export default class App extends Component {
  componentDidMount() { 
    //  Call api Interface and provides two parameters 
    let params = { type: 2, author: ' Beigu Green Tea ' }
    apiArticleEdit(params).then(res => { 
      //  Other actions after obtaining data successfully 
      //.....
      console.log(res)
    })
  }
  render() {
    return (
      <div>
        
      </div>
    )
  }
}

Other api interfaces, just continue to extend below in api. js. Friendly reminder, write notes for each interface! ! !

One advantage of api interface management is that we centralize api system 1. If we need to modify the interface in the later period, we will find the corresponding modification directly in api. js, instead of finding our interface on every page and then modifying it will be very troublesome. The key point is that the amount of 10,000 modifications is relatively large. Also, if you modify the interface directly in our business code, it is easy to move our business code accidentally and cause unnecessary trouble.

Ok, finally, the completed axios encapsulation code is presented.


// In index.js Introduce in axios
import axios from 'axios';
// Introduce qs Module to serialize post Data of type 
import QS from 'qs';
//antd Adj. message Prompt component, everyone can according to their own ui Component changes. 
import { message } from 'antd'

// Save environment variables 
const isPrd = process.env.NODE_ENV == 'production';

// Distinguish between development environment and production environment URL
export const basciUrl = isPrd ? 'https://www.production.com' : 'http://www.development.com'

// Settings axios Base path 
const service = axios.create({
  baseURL: basicUrl
})

//  Request interceptor 
service.interceptors.request.use(config => { 
  //  Does it exist in the local store before each request is sent token , can also be passed through Redux Here, we only demonstrate getting it locally token
  //  If it exists, it will be unified 1 In http Requested header Add them all token , so that the background is based on token Judge your login status 
  //  Even if it exists locally token , it is also possible token Is expired, so the return status should be judged in the response interceptor  
  const token = window.localStorage.getItem('userToken') || window.sessionStorage.getItem('userToken');
  // Add in each request token
  config.data = Object.assign({}, config.data, {
    token: token,
  })
  // Set the request header 
  config.headers = {
    'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'
  }
  // Serialize the request parameters, otherwise post Background reception of request parameters is abnormal 
  config.data = QS.stringify(config.data)
  return config
}, error => { 
    return error;
})

//  Response interceptor 
service.interceptors.response.use(response => {
  // Do different things according to the different status codes returned 
  //  Here 1 Be sure to negotiate with the back-office developers 1 Error status code of 
  if (response.code) {
    switch (response.code) {
      case 200:
        return response.data;
      case 401:
        // Handling method not logged in 
        break;
      case 403:
        //token Expired processing method 
        break;
      default:
        message.error(response.data.msg)
    }
  } else { 
    return response;
  }
})
// Finally, put the packaged axios Export 
export default service

Summarize


Related articles: