客户端后端研发的必修课

前言

本文从APP后端研发同学的角度,带来一些我们的思考和总结。

接口规范

客户端和服务端通常采用Http(s) 协议,JSON(P)数据格式交互。通常定义的JSON格式如下:

{
    "code": 0, //接口状态值
    "randomcode": "1515121404158",//随机状态码
    "md5": null, //用来判断数据是否更新
    "codeMsg": "成功", // 提示语,Toast使用
    "data": { //业务数据
    }
}

我们对JSON数据格式的基本要求如下:

  1. JSON数据格式要保持良好的结构,符合标准的JSON规范
    • key必须为字符串, 使用双引号而不是单引号 , 字段命名尽量做到见名知意,命名规则建议采用驼峰命名
    • 当Value值为null时,也需要返回对应的Key ,制定协议时包含哪些字段,都需要返回
  2. data 值的数据类型为Object,不允许修改。
{
    "data": {"list":[]} //good
    "data": []   // bad
    "data": "123123"  // bad
}
  1. status需要表示状态值时,字段从1+开始,0是一种未赋值的默认状态,1:进行中,2:待支付,3:已完成,4:已取消
  2. 客户端尽量只负责展示逻辑,不处理业务逻辑。
  3. 接口返回字段除了约定的必要字段,不允许返回多余的字段。
    反例:不定义Model,直接把底层的数据库表对应的Bean返回给前端,导致多传输很多不必要的字段。
  4. 不允许拿变量命名json的key值
//good
[{"name":"书籍1","chapters":500},{"name":""书籍2","chapters":180},{...},...]
//bad
[{"书籍1":500},{"书籍2":180},{...},...]
  1. 禁止程序拼接json字符串,防止包含特殊转义字符,导致客户端解析json失败

说明:此处没有统一iOS、Android、Server的JSON解析框架

通用设计

APP的后端系统有些设计是通用的,各APP可以相互借鉴。

  1. 通用参数
    对于一些客户端每次请求都需要的参数信息,我们暂且称之为通用参数,譬如:os、appid、appversion、channel、imei 等。对于这些信息客户端统一放在Header中。

  2. 接口签名
    接口签名的目的是保证服务端收到的请求都来自客户端,一定程度增加接口被抓取的难度。
    我们采用的方法是使用拦截器处理,客户端和服务端可以约定一些通用参数、时间戳等,前后端分别计算md5值,然后对比。
    示例代码如下:

@Override
public ActionResult preExecute(BeatContext beat) {
  HttpServletRequest request = beat.getRequest();

  String signVal = request.getHeader(HEADER_SIGN);
  if (StringUtils.isBlank(signVal)) {
    log.info("hsign is not exist.");
    RespJsonResult jsonResult = RespJsonResult.creatFailEntity(ResponseCodeConsts.AUTH_ERR_HEADER_NOT_EXIST, "guess error lowest");
    return new JsonViewResult(JsonHelper.toJSONString(jsonResult));
  }
  StringBuffer headerBuffer = new StringBuffer(100);
  for (String headerKey : headerKeylist) {
    String headerValue = request.getHeader(headerKey);
    if (headerValue != null && headerValue.trim().length() > 0) {
      headerBuffer.append(headerValue).append("_");
    } else {
      headerBuffer.append("null_");
    }
  }
  String source = headerBuffer.append("你的秘钥").toString();
  String localSign = MD5.encode(source);
  if (!signVal.equals(localSign)) {
    log.info("sign is illegal.source = " + source + ", localSign = " + localSign + ", hsign = " + signVal);
    RespJsonResult jsonResult = RespJsonResult.creatFailEntity(ResponseCodeConsts.AUTH_ERR_HEADER_NOT_PERMITTED, "guess error lower");
    return new JsonViewResult(JsonHelper.toJSONString(jsonResult));
  }
  return null;
}
  1. 配置中心
    动态化是一个APP的标配,小到一个icon的图标,大到一个页面模块的布局。特别是针对客户端这种 C/S 结构 ,各种开关、三方入口、动态链接等都需要从配置中心获取,不写死是我们的基本原则。
    另外,动态配置,从产品的角度,也可以灵活调整运营策略,达到快速试错的目的。
    整体架构见:


    客户端后端研发的必修课_第1张图片
    配置中心.png
  1. 跨域问题
    跨域问题是由于javascript语言安全限制中的同源策略造成的,简单来说,同源策略是指一段脚本只能读取来自同一来源的窗口和文档的属性,这里的同一来源指的是主机名、协议和端口号的组合。
    解决跨域问题通常采用JSONP和Access-Control-Allow-Origin。
  • JSONP
    JSONP的原理就是利用

你可能感兴趣的:(客户端后端研发的必修课)