响应报文适配器

2020/12/28

就是通过类型来区分返回哪种响应报文格式,为什么会有这方面的需求呢?因为随着项目变大,功能模块的扩展,前端可能会调用很多个服务(后端),这些服务可能是不同团队提供的,那么问题来了,不同服务返回的响应报文格式不统一,就拿最常见的列表来说

服务一返回报文格式如下:

{
  success: true,
  data: {
    list: [...],
    current: 1, // 当前页
    size: 10,   // 每页条数
    total: 20   // 总条数
  },
  message: ''
}

服务二返回报文格式如下:

{
  code: 0,
  data: {
    records: [...],
    pageNum: 1, // 当前页
    pageSize: 10,   // 每页条数
    total: 20   // 总条数
  },
  message: ''
}

还有的直接返回一个数组列表,这是没有分页的列表。总之返回的报文五花八门,所以为了方便前端展示,我们需要把不同的报文格式转化成同一种格式。

# 实现

假如有一个请求列表数据的接口如下:

export function fetchList (params) {
  return axios.get(`${BASE_URL}/list`, {
    params
  })
}

如果要对这个接口返回的报文进行适配,我们怎么做最方便呢?假如有一个函数直接对返回结果进行包装,就像下面这样

export function fetchList (params) {
  return resAdapter(axios.get(`${BASE_URL}/list`, {
    params
  }))
}

现在的工作就是实现 resAdapter 函数,axios.get 返回的是一个promise ,所以 fetchList 函数返回的也是一个 promise ,那么 resAdapter 函数返回的必然也是一个 promise

完整代码

const PAGE_SIZE = 10

export const TYPES = {
  // 带分页列表
  LIST_PAGINATION: 'LIST_PAGINATION',
  // 带分页列表 2
  LIST_PAGINATION_2: 'LIST_PAGINATION_2'
}

class Adapter {
  constructor (res, type) {
    for (const key in res) {
      if (Object.prototype.hasOwnProperty.call(res, key)) {
        this[key] = res[key]
      }
    }

    try {
      this[type]()
    } catch (e) {
      console.error('无效的适配器类型!')
    }
  }

  /* 适配带分页列表报文 */
  [TYPES.LIST_PAGINATION] () {
    const data = this.data || {}
    this.total = data.total || 0
    this.pageNum = data.current || 1
    this.pageSize = data.size || PAGE_SIZE
    this.pagination = {
      pageSize: +this.pageSize,
      pageNum: +this.pageNum,
      total: +this.total
    }
    this.list = data.records || []
  }

  /* 适配带分页列表2报文 */
  [TYPES.LIST_PAGINATION_2] () {
    const data = this.data || {}
    this.total = data.totalCount || 0
    this.pageNum = data.currentPage || 1
    this.pageSize = data.pageSize || PAGE_SIZE
    this.pagination = {
      pageSize: +this.pageSize,
      pageNum: +this.pageNum,
      total: +this.total
    }
    this.list = data.records || []
  }
}

export default async function resAdapter (resPromise, type = TYPES.LIST_PAGINATION) {
  const res = await resPromise
  return new Adapter(res, type)
}

Last Updated: 2023/9/28 下午6:37:34