三年不断优化更新的接口服务封装代码推荐,支持后端多种微服务对接,可多平台移植使用

2,487 阅读6分钟

碎碎念

看了下上次文章发布时间,2个月前。好久没更新了。技术深度方面也没有特别多的一个加深。这次来一个老生常谈的事情吧。api服务封装。这是我干前端这些年一步步慢慢优化过来的代码。

特性:

1、支持多个不同微服务(核心)

2、集中配置中心

3、简化开发流程和优化开发体验

4、解耦,可移植

一、列举下大家都是怎么封装的接口服务

我来吐槽下大家这些都会产生什么问题,我全部试过

1、增加接口拦截服务,什么重复接口防止提交

好多文章都在axios上面做文章,基于axios本身的api进行再封装。先不提缺点。本身你去拦截重复的路由最大的问题是项目越来越大之后,你一个页面两个地方用一个接口我问你怎么办?

2、防抖处理,优化业务代码,避免瞬间多次提交

这个封装的主要目的是为了我们像保存等操作按钮,避免瞬间提交两次以上。比如loading等方式并不是百分百没问题的。

但是这个因为你的防抖封装在全局,那么当一个瞬间有两个以上的api的时候,结果只有第一个api有效。别的api无法请求了。当然你愿意用class方式创建api,非要去new一个对象那就不存在这种情况了。

3、像后端一样用rest服务方式(ps:LJ)

这个我真的是觉得你们很S,我们封装的目的是为了节省代码量,不是让你增加代码量

post,get,delete全部写一个函数,你是不是闲得慌

4、好像在社区经常看见的就是这些方案

暂时先这样。

二、为什么要封装api服务?

1、让我们少写代码

为了省代码啊,大哥大姐们?我最受不了的就是那种什么都不封装,包括直接那axios直接api使用的项目了。你针对你单个业务环境还好,但是每个业务环境封装一个不闲累得慌啊。

还有,就是好多新手,老手老干的事情,就是直接怼上去。直接就是用。项目后期让你改个东西要疯,想上统一管理或者一些全局监听等等,唉……

2、业务痛点

当公司大一点之后你后端服务就不只是一个,必定是两个以上的服务。偏偏吧每个服务的返回值判断还不一定对。你非要在实际编写的时候一一判断吗?

你上手机端,pc端,小程序等等环境每次都重新封装一套?然后每次都需要为了这个服务不断更新换代?好痛苦啊。

还有一些项目需要直接就是全局loading等待接口的,单独写也是代码量啊

三、代码解析

项目地址:github.com/ht-sauce/to…

md文件更新不太及时。见谅哈

首先是目录结构

1、config.js

这个没什么特别的主要是根据不同的微服务进行一个提前配置

2、base文件

核心是axiosAjax.js,tips.js主要是为了把提示信息全局的拿出来。很多地方都需要进行使用

代码解析

可以看到本身其实非常的简单,主要是把axios先做了一次封装,参数大家应该都懂了。这里做了一个省代码操作,加入了emelent-ui的loading处理

这里的核心目的是解耦axios,方面我在后期比如移植到小程序环境下进行使用。那么我的核心api部分就可以解放出来,非常关键的地方。

import axios from 'axios'
import { Loading } from 'element-ui'

// axios函数封装
const ajax = ({
  url = '',
  loading = false, // 加载拦截
  baseURL = '',
  data = {},
  headers = { 'Content-Type': 'application/json;charset=UTF-8' }, // 头部信息处理
  method = 'get',
  timeout = 30 * 1000,
  responseType = 'json', // 表示服务器响应的数据类型,可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
}) => {
  // 接口全局加载提示
  let loadingInstance = ''
  if (loading !== false) {
    loadingInstance = Loading.service({
      lock: true,
      text: loading !== true ? loading : '加载中……',
      spinner: 'el-icon-loading',
      background: 'rgba(0, 0, 0, 0.5)',
    })
  }

  const posts = ['put', 'post', 'patch'] // 使用data作为发送数据主体

  return new Promise((suc, err) => {
    // 预处理数据部分
    method = method.toLocaleLowerCase() // 转化为小写
    axios({
      url: url,
      baseURL: baseURL,
      headers: headers,
      method: method,
      [posts.includes(method) ? 'data' : 'params']: data,
      timeout: timeout,
      responseType,
    })
      .then((response) => {
        loadingInstance && loadingInstance.close()
        suc(response)
      })
      .catch((e) => {
        loadingInstance && loadingInstance.close()
        err(e)
      })
  })
}

export { ajax }

3、couplingAjax.js解析

这里不贴全部代码了。说一下这里做了什么。

首先是入参部分

1、opt参数部分

比较特殊的几个参数file,isResponse,reLogin

file是比较特殊的,是因为file独立属于文件模式。因为项目的文件都需要口令校验才可以下载,那么就需要利用file参数,当文件下载模式的情况下,我们就不需要再去处理常规的业务流程了。

isResponse是因为我实际上会对代码的使用做一次优化,我们知道取返回参数的时候是需要data.data的。我这一步给省了,提前给你取好。这要又省了一点代码。但是有时候特殊情况需要完整的返回结构,根据后端的错误码或者其他字段定制定制信息。那么就需要放开该功能

reLogin很简单,接口都需要走授权口令,口令不通过需要跳转到登录页,传入false那么就不跳了

opt.error,默认为true,当接口报错的时候后端有错误信息,统一封装进行提示。可以传入false进行关闭。也可以传入字符串,把提示信息改为你要的提示信息

opt.success 和error参数同理

2、截图的中间部分

prefix = '', // 路由的前缀,这里会作为微服务的前缀拼接到每个路由前面,少写点代码
    codeField = 'success', // 成功判断字段
    dataField = 'data', // 快速取值字段
    codeNum = true, // 成功判断值
    msgField = 'message', // 提示信息或者错误信息
    tipsCode = 'errorCode', // 错误码

prefix特殊一点。等下index部分就知道怎么配置使用了

4、index.js入口文件解析

这个文件就很简单了,主要是让大家看一下prefix有什么用

5、apis文件的使用,根据微服务进行划分文件夹或者文件

根据微服务划分的文件和fil参数使用情况和基本配置

6、使用

import service from '@/services'

    async test() {
      try {
        // 正确信息
        const res = await service.Nbs.ceshi({ 
          url = '', // url地址
          loading: false, //加载拦截loaing,可以传入字符串更换提示信息  
          baseURL: '',  // 基础路径前缀
          data: {},  // 不管是get还是post参数都放这里
          headers: { 'Content-Type': 'application/json;charset=UTF-8' }, //头部信息处理  
          method: 'get',  // 访问方式
          timeout: 30 * 1000, // 接口超时时间
          error: true, // 错误提示信息:可以传入字符串,传入字符串则不管什么提示都是该字符串提示
          success: false // 成功信息提示:可以传入字符串,传入字符串则不管什么提示都是该字符串提示
          })
        console.log(res)
      } catch (e) {
        // 错误信息统一都在这里
        console.log(e)
      }
    }

四、总结和致谢

1、总体来说我根据不同服务进行划分,做到了一套封装多次使用

2、参数配置提取

3、解构axios,可以做到到处移植

感谢阅读,喜欢点赞