从清晰的RESTful接口到漂亮的系统设计

接口是系统与外界交互的窗口,其他系统通过接口可以知道你管理着哪些资源,他能对这些资源干些什么。
当然我们不遵守RESTful的建议也可以满足上面的目标,既然如此我们为什么还要按RESTful的规范来设计我们的接口呢?这样的灵魂拷问很现实也很真实,有小朋友会讲,我写接口都是一把梭,快得很,什么RESTful?不存在的。
在这里插入图片描述
那么我们先来聊一聊为什么要把接口给RESTful了,稍后再聊如何做,有哪些正例反例,以及如何以接口为开头来设计出漂亮的 DDD CQRS 的微服务系统。

为什么要写清晰的RESTful接口

  1. 技术人员也是要面子的,接口文档的交付也是一种技术人员的交手,高手过招在开打前,看你的架势就能大概知道你的水准,设计良好的接口会让对方感觉出你的基本功、设计理念、对技术运用的拿捏、对细节的关注。这就好比武林高手开打前先拉开架势互相观察一样。
  2. 在同样的规范下容易快速达成共识,减少不必要的解释。大家都遵从一样的规范,一看就明白这个接口是干嘛的了,省去了很多相互之间的误解以及沟通。一个眼神对方就明白你要干嘛了。
  3. RESTful的接口易于调用,与语言无关,有利于将服务提供给更多消费者。
  4. 它是面向资源的,能通过接口帮助我们描述我们的资源、资源的结构,能帮助我们去建立领域模型。
  5. 实现RESTful接口的文档与框架有很多,能为我们提供很多帮助与参考。
  6. 我们只要花很小的代价就能写好RESTful接口。

当然优点还会有很多,但是上面几个应该已经够了,特别是第一个,面子是最重要的。

RESTful的最佳实践

REST,Representational State Transfer的缩写,表现层状态转换,这个怎么理解呢?
其实这个和我们的程序是一样的,程序是什么?输入一个值,经过逻辑处理改变其状态,返回改变后的状态。
RESTful接口就是把这个值的输入通过http协议传输给到我们的处理逻辑,那么我们的程序如何知道要操作哪个资源,如何操作呢?是读取、创建、更新还是删除呢?
这就引出了另外两个在RESTful接口中很关键的显式要素了:URI和HTTP 请求方式。开始最佳实践前我们讲讲URI和HTTP 请求方式在这个过程中扮演什么角色:

  • URI ,指向我们要操作的资源,相当于解答了我是谁;
  • HTTP 请求方式,通过GET、POST、PUT、PATCH、DELETE告诉系统,他想对URI指向的资源干什么,解答了要干什么。

上面的文字还是会比较抽象,我们先来看个简单例子,我就用上周一位朋友发我的一个车牌号来举例:

请求方式URI要干什么
GETcars获取所有的车
GETcars/IPX-177获取车牌号为IPX-177的车
POSTcars/IPX-177创建一辆新的IPX-177车,但是在这里会失败,因为已经存在了
PUTcars/IPX-177修改IPX-177这辆车
PATCHcars/IPX-177部分修改车IPX-177
DELETEcars/IPX-177车开完了进入贤者模式,一切索然无味的时候,删除车IPX-177

例子举完了,开始讲解最佳实践前,希望大家对着这几个例子观察一下,细品一下,不要用快进模式,之后我们再来分享一些好的实践。

在这里插入图片描述

好的实践

  1. URI是指向资源的,不要带动词,动词由HTTP请求方式来带,我们看第一个例子,这个很简单但是却很不容易做到,回顾我们那些曾经写过的接口,应该很多都在URI里带了动词;
/**
 * 获得车牌对应数据
 */
//正例
/cars/ipx-177

//反例
/getCar?id=ipx-177
  1. 资源的单词用复数,且尽量易懂,这样便于我们对资源做进一步定位,最重要的是便于接口使用者理解和使用,要用做产品的心来做接口,因此接口应该对使用者友好;
//正例
/cars/ipx-177

//反例
/car
  1. 通过{id}及子资源构成的URI能定位到一条链路上的资源,如我们的例子2;
//正例
/cars/ipx-177

//反例
/car?id=ipx-177
  1. 在URI中带有大版本号,在header中携带小版本号;
//正例
https://phoenix.force/v1/cars
Accept: json; version=1.1

//反例
https://phoenix.force/v1.1/cars

//正例
https://phoenix.force/cars
  1. 为集合查询接口提供对筛选、排序、分页、返回字段的支持。只有这样的集合查询接口,才是具备好的扩展性与设计的接口。
//正例
cars?cup>C&fields=type,title,des&sort=-create_time&from=1&size=10

//反例
不支持就是反例了
  1. 使用Http状态码处理错误,在返回JSON数据中返回具体原因。
  2. 使用TOKEN进行状态管理,而不是session或cookie。
  3. 打开gzip压缩。
  4. 让你的新增、修改、删除接口做好幂等。
  5. 不要手工维护接口文档,更不要久不更新让文档与实现不同步,使用工具帮你实现代码就是接口文档。

其实常用的建议就这些了,不要贪多,建议不是越多越好,能把上面10条做好已经很不容易了,相信我。

让你的RESTful接口充满恨

我们看了一些好的实践,那么肯定也有不好的,其实这个部分甚至比上面好的实践更重要,为什么呢?
这个就像兵法一样,我们用兵法首先是要干嘛? 首先是让自己活下去,这里也是我们先不追求做得有多好,我们先不要让自己的接口引来仇恨的炮火。

  1. 用自定义的奇怪格式定义接收或返回数据。
  2. 新增、修改、删除接口没有做幂等。
  3. 接口文档与接口实现已经对不上了。
  4. 返回码乱七八糟,含糊不清,对于问题定位起不到任何帮助。
  5. 接口没有版本概念,一升级就把调用方全部往死路上逼。

如果你恨一个人,请按以上5点提供接口供对方调用。

未来的一些趋势

这里做一些简单介绍,有兴趣的小伙伴可以先自行搜索查看,我们后续也会陆续进行分享。
学习的一个好途径依然是看官方文档,这个不会错。

  • GraphQL
  • HATEOAS
  • WebFlux

开篇讲的从清晰的RESTful接口到漂亮的系统设计,这里我们是不是还没讲到漂亮的系统设计,DDD、CQRS什么的?别急,这篇我们先到这里,因为漂亮的系统设计其实是一个系统性问题,在这里我们尽量先把涉及到的一些方方面面都简单讲一下,最后一组装,好的系统设计就水到渠成了。不然我们干巴巴的讲系统设计太生硬了,效果不好,这必须结合一些基础知识,业务场景,组织架构一起来讲,要带到环境里场景里。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值