# 请求插件

@sula/plugin-fetch,是用于向服务器发起请求的插件,是Sula内部的form和table类组件及模板内部请求相关的能力的基础

插件使用示例:

// 插件使用
import FetchPlugin from "@sula/plugin-fetch";

sula.fetch(ctx, config.remoteValues).then((data: any) => {
  ctx.form.setFieldsValue(data);
});

结合umi-plugin-sula,我们也可以对请求插件的能力直接使用

//确保项目引用了umi-plugin-sula
import { fetch } from "@sula/biz";

fetch({
  url: '/user/12345',
  method: 'get',
  params: {
    firstName: 'Fred',
    lastName: 'Flintstone'
  },
  responseType: 'response',
  disableSuccessMessage: true,
  disableErrorMessage: true,
  // 更多参数参考x👇FetchOptions
}).then(
  res => {
    // resolve
  },
  () => {
    // reject
  },
);

# API

FetchOptions,请求配置属性如下:

# url

  • 类型:string
  • 默认值: -

用于请求的服务器 URL

# method

  • 类型:string
  • 默认值:'get'

请求方式

# params

  • 类型:object
  • 默认值: -

即将与请求一起发送的 URL 参数

# extraParams

  • 类型:object
  • 默认值: -

params的补充,与params进行合并

# convertParams

请求参数转换。我们可以注册对应类型为convertParams的插件,详情参考插件规范-类型插件TypePlugin

示例:

convertParams: (ctx) => {
  console.log('params: ', ctx.params);
  return {...ctx.params, seq: 1}
}

# converter

返回数据转换。我们可以注册对应类型为converter的插件,详情参考插件规范-类型插件TypePlugin

示例:

converter: (ctx) => {
  console.log('fetch data: ', ctx.data);
  return ctx.data;
}

# successMessage

  • 类型:string
  • 默认值: -

自定义成功message,默认不开启

示例:

successMessage: '数据提交成功'

# disableSuccessMessage

  • 类型:boolean
  • 默认值:false

非get请求时是否弹出成功提示,默认弹出

# disableUserErrorMessage

  • 类型:boolean
  • 默认值:false

是否弹出用户级别错误提示,默认弹出

# disableDevErrorMessage

  • 类型:boolean
  • 默认值:false

是否弹出开发级别错误提示

# disableErrorMessage

  • 类型:string
  • 默认值: -

是否弹出开发级别和用户级别错误提示,不建议使用该字段

tips

更多配置参数参考Axios配置

# beforeFetch

  • 类型:(ctx, config) => boolean | Promise|TypePlugin
  • 默认值: -

是否继续进行fetch请求

tips

beforeFetch如果返回false或者Promise<reject>,那么fetch请求将返回Promise<reject>

# 实例方法

使用者可以基于全局配置可以实现统一的逻辑处理流程(你可以把它理解为middleware),也可以针对某个特定的url进行配置处理。例如使用的是umi,你可以在global.js中进行配置。

示例:

// global.js 
import FetchPlugin from '@sula/plugin-fetch';
// 全局配置
FetchPlugin.use({
  bizErrorAdapter(response) {
    if(response.success === false && response.code > 333) {
      return {
        message: response.msg,
        description: response.desc,
    }}
  }
})

// 针对某个url的配置
FetchPlugin.use('/task/v1/info', {
  bizErrorAdapter(response) {
    if(response.success === false && response.code > 333) {
      return {
        message: response.msg,
        description: response.desc,
    }}}
})

实例方法作用生命周期图:

sula-plugin-fetch

# errorHandler()

errorHandler(error) {
  if (!error.response) {
    alert('Network Error')
  }
};

网络错误

# bizRedirectHandler()

//默认方法
bizRedirectHandler(response) {
  const { data, code } = response;
  if (Number(code) === 302 && data) {
    window.location.href = data;
  }
  return response;
};

业务重定向

# bizErrorAdapter()

//默认方法
bizRedirectHandler(response) {
  const { code, success, message, description } = response;
  if (success === false) {
    return {
      message: message || code,
      description: description || message || codeMessage[code],
    };
  }
  return null;
};

错误信息转换,返回对象属性如下:

参数 说明 类型
code 响应状态码,可用于详细判断接口 number
data 业务数据 any
success 接口调用结果,可用于简单判断接口是否成功 boolean
message 前端展示信息,多用于错误信息展示 string
description 错误详细描述,多用于开发排查问题 string

详情参考:接口规范

# bizNotifyHandler()

示例:

bizNotifyHandler (response, errorDesc, notifyOptions) {
  const {
    method,
    disableSuccessMessage,
    disableErrorMessage,
    disableDevErrorMessage,
    disableUserErrorMessage,
    successMessage,
  } = notifyOptions;

  const { code, message } = response;

  const opCode = Number(code);
  /** 错误处理 */
  if (errorDesc) {
    if (disableErrorMessage !== true) {
      /** 非用户级错误提示 */
      if (disableDevErrorMessage !== true && opCode >= 300) {
        notification.error({
          message: errorDesc.message,
          description: errorDesc.description,
        });
        /** 用户级别错误提示 */
      } else if (disableUserErrorMessage !== true) {
          message.error(errorDesc.message);
        }
    }

    return response;
  }

  /** 非get请求提示 */
  if (disableSuccessMessage !== true && method !== 'get') {
    message.success(successMessage || message || defaultSuccessMessage);
  }

  return response;
};

错误提示统一处理,方法入参为

参数 说明 类型
response 接口返回 any
errorDesc 错误描述 bizErrorAdapter方法返回值
notifyOptions 提示配置 { method, disableSuccessMessage, disableErrorMessage, disableDevErrorMessage,disableUserErrorMessage,successMessage} 详情参考API

# bizCatchHandler()

bizCatchHandler(errorDesc, response) {
  console.log('bizCatchHandler', response);
};

开发级错误,即接口返回success === false时,用户对错误的处理方法。方法入参为:

参数 说明 类型
errorDesc 错误描述 bizErrorAdapter方法返回值
response 接口返回 any

# bizDataAdapter()

bizDataAdapter(response) {
  if (response && response.data) {
    return response.data;
  }
  return response;
};

收集接口返回数据中的有效数据data

# bizParamsAdapter()

bizParamsAdapter(params) {
  params.uuToken = '123456';
  return params;
}

对所有请求接口进行全局的参数处理,每个接口各自的参数处理方法convertParams会优先于该方法执行

# bizQueryAdapter()

bizQueryAdapter(query) {
  query.ctoken = getToken(); // 每次请求添加动态生成的ctoken
  return query;
}

# 开发规范

使用请求插件,建议后端返回数据字段如此定义:

{
  data, // 前端消费数据
  message, // 后端的反馈提示
  description, // 后端的反馈详情
  code, // 后端定义的code码
  success, // 后端定义的请求成功与否
}

基于以上字段,请求插件定义了四种场景:

  • 正常
    { code: 200, success: true}
    
  • 重定向
    { code: 302, success: true, data: 'redirect url'}
    
  • 用户级错误请求
    { code: 200, success: false, message: 'error message'}
    
  • 开发级错误请求
    { 
      code: 500, // code >= 300
      success: false, 
      message: 'error message',
      description: 'error detail',
    }
    

默认状态码对应描述:

const codeMessage = {
  400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。',
  401: '用户没有权限(令牌、用户名、密码错误)。',
  403: '用户得到授权,但是访问是被禁止的。',
  404: '发出的请求针对的是不存在的记录,服务器没有进行操作。',
  406: '请求的格式不可得。',
  410: '请求的资源被永久删除,且不会再得到的。',
  422: '当创建一个对象时,发生一个验证错误。',
  500: '服务器发生错误,请检查服务器。',
  502: '网关错误。',
  503: '服务不可用,服务器暂时过载或维护。',
  504: '网关超时。',
};
Last Updated: 2020/1/15 下午3:27:09