2018-01-08

高诚智能家居协议思考

借此机会重新理顺一下智能家居部分的网络通讯协议使用情况,并总结一下做为指导。当然只是抛砖引玉,需要大家一起商议后决定。

规范

首先定义一些规范,提出一些硬性要求。

URI规范

URI 表示资源,资源一般对应服务器端领域模型中的实体类。

  1. 不用大写
  2. 用中杠-不用下杠_
  3. 参数列表要encode
  4. URI中的名词表示资源集合,使用复数形式

JSON规范

  1. 不要使用缩写
  2. 统一用驼峰命名法
  3. 不要使用_或者-
  4. 用名词复数表示集合类型

Http部分

规定

  • App的初始化数据尽量都用http协议获取
  • 页面的初始化数据尽量都用http协议获取

待定

MQTT部分

使用场景

  • 所有对智能家居的设备、传感器等硬件操作都尽量使用MQTT协议
  • 所有需要双向通讯(确切的说是需要后台主动推送给前端的情景)的部分都尽量使用MQTT协议

使用列举

主机操作

  1. 主机布防状态变更

传感器操作

  1. 传感器状态变更

设备操作

  1. 设备状态变更

界面相关

  1. 消息提示:比如底部导航栏的tab勋章提示

错误处理

  1. 不要发生了错误但给2xx响应,客户端可能会缓存成功的http请求;
  2. 正确设置http状态码,不要自定义;
  3. Response body 提供 1) 错误的代码(日志/问题追查);2) 错误的描述文本(展示给用户)。

对第三点的实现稍微多说一点:

Java 服务器端一般用异常表示 RESTful API 的错误。API 可能抛出两类异常:业务异常和非业务异常。业务异常由自己的业务代码抛出,表示一个用例的前置条件不满足、业务规则冲突等,比如参数校验不通过、权限校验失败。非业务类异常表示不在预期内的问题,通常由类库、框架抛出,或由于自己的代码逻辑错误导致,比如数据库连接失败、空指针异常、除0错误等等。

业务类异常必须提供2种信息:

  1. 如果抛出该类异常,HTTP 响应状态码应该设成什么;
  2. 异常的文本描述;

在Controller层使用统一的异常拦截器:

  1. 设置 HTTP 响应状态码:对业务类异常,用它指定的 HTTP code;对非业务类异常,统一500;
  2. Response Body 的错误码:异常类名
  3. Response Body 的错误描述:对业务类异常,用它指定的错误文本;对非业务类异常,线上可以统一文案如“服务器端错误,请稍后再试”,开发或测试环境中用异常的 stacktrace,服务器端提供该行为的开关。

常用的http状态码及使用场景:

状态码 使用场景
400 bad request 常用在参数校验
401 unauthorized 未经验证的用户,常见于未登录。如果经过验证后依然没权限,应该 403(即 authentication 和 authorization 的区别)。
403 forbidden 无权限
404 not found 资源不存在
500 internal server error 非业务类异常
503 service unavaliable 由容器抛出,自己的代码不要抛这个异常
错误描述
{
  "error": {
    "message": "java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $",
    "code": 500,
    "exception": {
      "class": "com.google.gson.JsonSyntaxException",
      "message": "java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $",
      "localized-message": "java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $",
      "cause": "java.lang.IllegalStateException"
    }
  }
}
错误请求头
{
  "date": "Mon, 08 Jan 2018 03:07:08 GMT",
  "server": "nginx/1.10.3 (Ubuntu)",
  "connection": "keep-alive",
  "content-length": "237",
  "content-type": "application/json"
}

接口版本(Versioning)

个人倾向于将版本号放在HTTP/MQTT头信息中,虽然不如放入URL中更直观,但是不方便我们统一管理,因为在前端URL是拼出来的String,请求头是统一个对象去设置,除非有特殊情况,某一个接口需1.0版本,某一个接口需2.0版本,这就另当别论,到时候统一商量,在拼这个URL的时候,放到固定目录(位置),如:smarthome.aghl.com:8080/版本(一般用v1、v2)/user 统一放在一级目录,这样的前端在拼接的时候,统一放到某个位置,也就方便管理了。

URL失效

随着系统发展,总有一些API失效或者迁移,对失效的API,返回404 not found 或 410 gone;对迁移的API,返回 301 重定向。

安全

待定

参考

  • http://www.ruanyifeng.com/blog/2011/09/restful.html
  • http://www.ruanyifeng.com/blog/2014/05/restful_api.html
  • https://demo.openhab.org:8443/doc/index.html

你可能感兴趣的:(2018-01-08)