美文网首页
2018-01-08

2018-01-08

作者: fight2048 | 来源:发表于2018-01-08 12:53 被阅读20次

    高诚智能家居协议思考

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

    规范

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

    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<u>/版本(一般用v1、v2)/</u>user 统一放在一级目录,这样的前端在拼接的时候,统一放到某个位置,也就方便管理了。

    URL失效

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

    安全

    待定

    参考

    相关文章

      网友评论

          本文标题:2018-01-08

          本文链接:https://www.haomeiwen.com/subject/otqbnxtx.html