查看原文
其他

【316期】面试官问:如何编写符合 REST 架构风格的 RESTful API?

Java精选 2022-08-09

点击上方“Java精选”,选择“设为星标”

别问别人为什么,多问自己凭什么!

下方有惊喜,留言必回,有问必答!

每一天进步一点点,是成功的开始...

REST这个词是2000年Roy Fielding在他的博士论文中提出的,Fielding参与了http协议的设计,也是Apache web server项目的参与者。他的这篇博士论文可以说对互联网的软件设计产生了深远的影响。但是从字面上理解REST(Representational State Transfer, 表现层状态转移)是非常抽象的。因此,本篇文章试图将REST进行拆解,分别从以下几个部分来进行解读:

Resource 资源

REST忽略了主语,全称应该是资源的表现层状态转移。所谓资源就是互联网上的各种资源,比如文本、图片、音频、视频等。在互联网上通过URI指定唯一的资源,所谓的’上网‘就是通过调用资源的URL来跟互联网上的一系列资源进行互动。

注:URI只代表资源的实体,严格地说,有些网址最后的.html后缀名是不必要的,因为这个后缀名表示格式,属于"表现层"范畴,而URI应该只代表"资源"的位置。

Representational 表象

资源可以有各种具体的表现形式,比如文本可以有xml格式,html格式,json格式,甚至是二进制格式,图片可以有PNG格式,JPEG格式等。资源的一个具体表现形式,应该在HTTP请求的头信息中用AcceptContent-Type字段指定,这两个字段才是对"表现层"的描述。

State Transfer 状态转移

通过http动词来实现资源的状态转移,用GET来请求资源,用POST来新建资源,用PUT来更新资源,用DELETE来删除资源。

简明扼要的总结REST:

  • 用URI来定位具体的资源

  • 用HTTP请求的Content-Type字段来描述资源的表现形式

  • 用HTTP动词来描述对资源的具体操作


RESTful API设计总结

随着近年来移动互联网的发展,各种客户端出不穷:Web,IOS,Android。因此需要一种机制使得各种客户端能够和服务端进行通讯,这就使得RESTful API的架构流行起来。RESTful是REST(表现层状态转化)的形容词形式,因此RESTful API就可以理解成“符合REST风格的API”。

格式规范

根据RFC3986定义,URL是大小写敏感的。所以为了避免歧义,尽量使用小写字母。

另外,推荐下 Spring boot 的用户权限管理系统开源项目:

https://gitee.com/yoodb/jing-xuan

RESTful API 应具备良好的可读性,当url中某一个片段(segment)由多个单词组成时,建议使用 - 来隔断单词,而不是使用 _。这主要是因为,浏览器中超链接显示的默认效果是文字并附带下划线,如果API以_隔断单词,二者会重叠,影响可读性。

/api/featured-post/     # GOOD
/api/featured_post/     # WRONG

协议

提供给用户的API,总是使用HTTPs协议。使用HTTPs协议还是HTTP协议本身和RESTful API并无关系,但是这对于提高网站的安全性很重要。另外,搜索公众号Java精选,后台回复“电子书”,获取一份惊喜礼包。

域名

API应该放在专有域名下,比如https://api.example.com/v1。也可以简单地把版本放在URL中,比如https://www.example.com/api/v1

版本

API的版本号应该放在URL中:

https://api.example.com/v1/

名词应该使用复数

所用的名词往往和数据库的表名对应,而数据库的表是一组记录的集合,因此URL中的名词即表示一组资源的集合,故URI中的名词要使用复数

https://api.example.com/v1/students
https://api.example.com/v1/schools
https://api.example.com/v1/employees

URL中不能使用动词

URI代表着一个资源,是一个实体,应该是名词,而不要把具体的动作放在URL中,对资源的操作应该通过HTTP的动词来实现。

不符合CRUD的情况

如果实在无法表示,也可使用动词,例如search没有对应的HTTP方法,可以在路径中使用search,更加直观

http://api.xxx.com/apiv3/search?timestamp=123213218&user_id=4192121&keyword=2134789。再例如创建了博客网站,如果想要发布一个博客,可以使用POST /articles/{:id}/publish

用HTTP动词表示对资源的操作

使用HTTP协议里的动词来实现资源的获取、删除、添加等操作

另外,推荐下Spring cloud的通用微服务开源项目:

https://gitee.com/yoodb/jingxuan-springcloud

  • GET:从服务器获取资源

  • POST:在服务器新建一个资源

  • PUT:在服务器更新资源(客户端提供改变后的完整资源)

  • PATCH:在服务器更新资源(客户端提供改变的属性)

  • DELETE:从服务器中删除资源

GET     https://api.example.com/v1/schools                  # 列出所有学校
POST    https://api.example.com/v1/schools                  # 新建一个学校
GET     https://api.example.com/v1/schools/ID               # 列出指定学校的信息
DELETE  https://api.example.com/v1/schools/ID               # 删除指定学校

GET     https://api.example.com/v1/schools/ID/students      # 列出指定学校的所有学生
DELETE  https://api.example.com/v1/schools/ID/students/ID   # 删除指定学校的指定学生

HTTP状态码

  • 200 OK - [GET]:服务器成功返回用户请求的数据

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

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

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

  • 401 UNAUTHORIZED:表示用户没有权限(令牌、用户名、密码错误)

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

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

其它

API的身份认证应该使用OAuth 2.0框架
服务器返回的数据格式,应该尽量使用JSON,避免使用XML。JSON有可读性强,结构紧凑,支持的语言种类多的特点,因此JSON是RESTful API最常用的返回格式。

作者:智明书

https://www.jianshu.com/p/955eb2faa354

公众号“Java精选”所发表内容注明来源的,版权归原出处所有(无法查证版权的或者未注明出处的均来自网络,系转载,转载的目的在于传递更多信息,版权属于原作者。如有侵权,请联系,笔者会第一时间删除处理!

------ THE END ------

精品资料,超赞福利!

☆ 主流Java进阶技术(学习资料分享)


3000+ 道各类技术面试题在线刷,最新、最全 Java 面试题!

期往精选  点击标题可跳转

【307期】从实现原理来讲,Nacos 为什么这么强?

【308期】Java 实现 10 万,并发去重,优雅地处理重复请求!

【309期】Spring Bean 容器启动耗时统计分析

【310期】Spring Cloud 分布式 WebSocket 集群解决方案

【311期】4种方法,实现多线程按照指定顺序执行

【312期】天坑!常见的 update 语句很容易造成 Bug 问题

【313期】SpringBoot 无侵入式,实现 API 返回统一 JSON 格式

【314期】Spring Cloud OpenFeign 接口反序列化失效,该如何解决?

【315期】面试官问:在大数据量情况下,如何优化 ElasticSearch 查询?

 技术交流群!

最近有很多人问,有没有读者交流群!想知道如何加入?方式很简单,兴趣相投的朋友,只需要点击下方卡片,回复“加群”,即可无套路入交流群!

文章有帮助的话,在看,转发吧!

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存