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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RESTful是一种基于HTTP协议的软件架构风格,旨在使网络服务可以通过统一的接口进行访问。API接口是应用程序开发者用来与其他软件系统进行交互的一组规定接口。API接口RESTful设计是将API接口设计符合RESTful架构风格的原则。RESTful设计主要有以下几个特点: 1. 资源定位:RESTful设计中,每个API接口都代表一个资源,通过URL定位资源,以类似于文件路径的形式来表示。例如,GET /users表示获取所有用户的资源。 2. 资源状态转换:RESTful设计强调使用HTTP动作(GET、POST、PUT、DELETE等)对资源进行状态转换。例如,使用POST方法向/users资源发送请求表示创建一个新用户。 3. 无状态:RESTful设计强调每个请求是独立的,服务器不会记录客户端的状态信息。每个请求都应该包含足够的信息来描述请求的目的。 4. 统一接口RESTful设计追求接口的统一性,即使用相同的接口规范来进行不同资源的访问,使接口规范更加简洁。 5. 可缓存:RESTful设计支持缓存,客户端可以将服务器返回的资源进行缓存,以减少对服务器的请求。 6. 分层架构:RESTful设计中,各个组件之间可以进行分层,每个组件只需关注与自己相邻的组件的交互,提高了系统的可扩展性和可维护性。 通过RESTful设计,API接口可以更加灵活和通用,能够更好地满足不同应用程序与软件系统之间的交互需求,并提供良好的可扩展性和可维护性。这种设计风格已经被广泛应用于Web服务、移动应用程序等领域,成为了一种主流的接口设计方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值