微服务接口设计规范

1 接口评价标准

一个好的接口设计通常需要满足以下几点:

  1. 简单:满足需求的同时,越简单越好。

  2. 易懂:优秀的API可读性好,尽量做到不需要文档就能读懂接口名称、参数的大概含义,提供给第三方的的接口要进行详细地描述。包括参数的取值范围、错误码、异常返回规则、SLA相关指标等。

  3. 一致:对于同一公司、站点提供的API,最好有同一的规则,让开发者只要看过几个API后,基本能猜到剩余API的含义。

  4. 稳定:最好在开始的时候就考虑好,不要轻易修改API,否则会给使用方造成麻烦。

  5. 安全:设计时要考虑超出预期的情况如何处理,给出被限流的情况。如果提供给第三方,则要考虑如何认证。

2 接口设计原则

  • 单一职责
    单一性是指接口要做的事情应该是一个比较单一的事情,比如登陆接口,登陆完成应该只是返回登陆成功以后一些用户信息即可。
  • 开闭原则
    对扩展开放,对修改关闭。需对变化封装:

(1)将相同的变化封装到一个接口或抽象类中 ;

(2)将不同的变化封装到不同的接口或抽象类中,不应该有两个不同的变化出现在同一个接口或抽象类中。 封装变化,也就是受保护的变化,找出预计有变化或不稳定的点,为这些变化点创建稳定的接口。

  • 接口隔离原则
    使用多个专门的接口,而不使用单一的总接口。 其实接口隔离原则说白了就是单一职责的扩展。
    对于一个比较细化的接口,更有利于书写单元测试,也更有利于调试。

  • 高内聚低耦合
    一个接口要包含完整的业务功能,而不同接口之间的业务关联要尽可能的小。

  • 安全性原则
    安全性问题是一个接口必须要保证的规范,可使用token(常用参数appid,appkey,timestamp,nonce,sign)、白名单、防刷、限流、隔离等手段保证接口调用的合法合规合理调用。

  • 兼容性原则
    接口设计要尽量考虑接口不同版本的兼容性,尽量避免升级的过程中不出现兼容性问题。
    如果修改API不可避免,那么最好是通过增加接口而不是修改已有接口来兼容。如果一定要改变已有接口,也要通过明确的版本号加以区分。

3 接口设计方法论

接口设计时,需要重点考虑一下问题:

  • 接口的命名。
  • 请求参数。
  • 支持的协议。
  • TPS、并发数、响应时长。
  • 数据存储。DB选型、缓存选型。
  • 是否需要依赖于第三方。
  • 接口是否拆分。
  • 接口是否需要幂等。
  • 防刷。
  • 接口限流、降级。
  • 负载均衡器支持。
  • 如何部署。
  • 是否需要服务治理。
  • 是否存在单点。
  • 接口是否资源包、预加载还是内置。
  • 是否需要本地缓存。
  • 是否需要分布式缓存、缓存穿透怎么办。
  • 是否需要白名单。
  • 架构设计时,可以根据场景的应用情况来做checklist。

4 Dubbo接口规范

4.1 Dubbo协议适用范围

Dubbo缺省协议采用单一长连接和NIO异步通信,适合于小数据量(传入传出参数数据包建议小于100k)大并发的服务调用。
反之,Dubbo缺省协议不适合传送大数据量的服务,比如传文件,传视频等,除非请求量很低。

4.2 命名规范

com.xxx.xxdomain.子系统.自定义接口名

4.3 粒度

  • 对外服务接口尽可能大粒度,每个服务方法应代表一个功能,而不是某功能的一个步骤,否则将地面临分布式事务问题,Dubbo暂未原生提供分布式事务支持,同时也可以减少网络交互。
  • 服务接口建议以业务场景为单位划分,并对相近的业务做抽象,防止接口数量爆炸。
  • 不建议使用过于抽象的通用接口,如Map query(Map),这样的接口没有明确语义,会给后期维护带来不便。

4.4 版本及兼容性

  • 每个接口都应定义版本号,为后续不兼容升级提供可能。
  • 建议使用两位版本号,第一位主版本号,第二位次版本号,只有不兼容时才需要变更服务主版本。
  • 当不兼容时,先升级一半提供者为新版本(通常在验证或低压力时间段),再将消费者全部升级为新版本,然后将剩下的一半提供者升为新版本。
  • 服务接口增加方法,或服务模型增加字段,可向后兼容。
  • 删除方法或删除字段,将不再兼容,枚举类型新增字段也不兼容,需要通过变更版本号升级。

4.5 异常

  • 建议使用异常报告错误,而不是返回错误码,异常能携带更多信息,并且语义更又好。
  • 如果担心性能问题,在必要时,可以override掉异常类的fillInStackTrace()方法为空方法,使其不拷贝栈信息。
  • 查询方法不建议抛出checked异常,否则调用方在查询时将过多的try…catch,并且不能进行有效处理。
  • 服务提供方不应将DAO或SQL等异常抛给消费方,应在服务实现中对消费方不关心的异常进行包装,否则可能出现消费方无法反序列化相应异常。

4.6 其它Tips

  • 服务参数及返回值建议使用POJO对象。
  • 建议Provider端对输入参数进行校验。
  • Provider端尽量多配置Consumer端的属性,让provider的实现者一开始就思考provider端的SLA。

5 RESTful接口规范

5.1 协议

考虑到服务的安全性,建议使用https作为API的通信协议,当然http也是可以的。

5.2 URL约定

URL格式:http(s)😕/server.com/{domain}/{version}/api-name。

  1. 其中domain是各个子系统领域,可以根据需要分层,但最好不要超过2层。
  2. 不用大写。
  3. 建议用中杠-,不用下划线_。
  4. 路径中不能有动词,只能有名词。名词表示资源集合,要使用复数形式。在RESTful架构中,每个网址代表一种资源(resource),所以网址中不能有动词,只能有名词,而且所用的名词往往与数据库的表格名对应。
  5. 词根规范
动作前缀备注
获取getget{XXX}
新增addadd{XXX}
修改updateupdate{XXX}
保存savesave{XXX}
删除deletedelete{XXX}
上传uploadupload{XXX}

5.3 数据格式

使用JSON作为微服务提交和返回数据的通用语言。
使用HTTP状态码来传达服务调用的状态。

5.4 请求参数

  • 动词释义
请求方式描述
GET获取数据
POST新增数据
PUT更新数据
DELETE删除数据
  • 请求参数

1)Query:是指请求的参数,一般是指URL中?后面的参数。

2)Header:请求头,存放公共参数、requestId、token、加密字段等。

3)Body:请求体,存放请求接口的参数数据。

  • 版本信息

    考虑到服务接口的平滑升级,可以将API的版本号放入URL,也可以将版本号放在HTTP头信息中,但不如放入URL方便和直观。
    
  • 过滤信息

请求信息应该为集合提供过滤、排序、选择和分页等功能。

1)Filtering过滤

使用唯一的查询参数进行过滤:如GET /cars?color=red 返回红色的cars。

2)Sorting排序

   允许针对多个字段排序:如GET /cars?sort=-manufactorer,+model  #这是返回根据生产者降序和模型升序排列的car集合。

3)Field selection选择

   给API消费者一个选择字段的能力,这会降低网络流量,提高API可用性。如GET /cars?fields=manufacturer,model,id,color。

4)Paging分页

  使用 limit 和offset.实现分页。如GET /cars?offset=10&limit=5。有时候为了将总数发给客户端,可以使用订制的HTTP头:如X-Total-Count。

5.5 返回参数

  • 返回包体格式
参数类型说明备注
codeNumber结果码
showMsgString显示信息
errorMsgString错误信息
dataObject数据JSON 格式
  • 返回码

http协议标准返回码及含义如下:

200 OK [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)

201 CREATED [POST/PUT/PATCH]:用户新建或修改数据成功

202 Accepted [*]:表示一个请求已经进入后台排队(异步任务)

204 NO CONTENT [DELETE]:用户删除数据成功

400 INVALID REQUEST [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的

401 Unauthorized [*]:表示用户没有权限(令牌、用户名、密码错误)

403 Forbidden [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的

404 NOT FOUND [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的

406 Not Acceptable [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)

410 Gone [GET]:用户请求的资源被永久删除,且不会再得到的

422 Unprocesable entity [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误

500 INTERNAL SERVER ERROR [*]:服务器发生错误,用户将无法判断发出的请求是否成功

  • 幂等说明

幂等:请求一次和请求多次的效果是一样的。

GET:由于GET请求仅仅是获取资源 并不修改资源,所以能保证幂等。

PUT:同样的请求,修改一次和修改多次是一样的,能保证幂等。

DEL:同理,能保证幂等。但是多次请求,只有第一次能返回200,其他都应该是404。

POST:不幂等,多次请求会在数据库表中生成多条记录。

因此,对POST的接口幂等性需要在业务代码上去实现。

  • 0
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值