简单介绍下RESTful Api

100 阅读7分钟

在之前的面试过程中,就被问到了什么是RESTful Api。当时的话在这个上面吃了亏,其实也有一直听说RESTful,但就是没有好好去了解过。那么今天就来看看它到底是个啥。

概念

REST(Representational State Transfer),直译是表现层状态转移,是一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。

资源

REST中省略了主语,主语就是”资源“,表现层指的是资源的表现层。所谓”资源“,就是网络上的一个实体,或者说是网络上的一个具体信息。可能对应到我们日常开发中,说”资源“是一个数据库表会更容易理解,当然不仅仅只是只数据库表。如果想要访问资源,调用它的URI(统一资源定位符)就可以。

表现层(Representational)

把”资源“具体呈现出来的形式,叫做它的表现层。比如,文本可以用txt格式表现,也可以用json格式来表现,图片可以用JPG格式来表示。

状态转化

访问一个网站,就代表了客户端和服务器的一个互动过程。在这个过程中,势必涉及到数据和状态的变化。
互联网通信协议HTTP协议,是一个无状态协议。这意味着,所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生"状态转化"(State Transfer)。而这种转化是建立在表现层之上的,所以就是"表现层状态转化"。
客户端用到的手段,只能是HTTP协议。具体来说,就是HTTP协议里面,几个表示操作方式的动词:GET、POST、PUT、DELETE等。

最佳实践

1.URL设计

1.1 动词+宾语

RESTful的核心思想就是,客户端发出的数据操作指令都是”动词+宾语“的结构。比如, GET /articles这个命令,GET是动词,/articles是宾语。动词通常就是五种HTTP的方法,对应CRUD操作。

  • GET:读取(Read)
  • POST:新建(Create)
  • PUT:更新(Update)
  • PATCH:更新(Update),通常是部分更新
  • DELETE:删除(Delete)

1.2 动词的覆盖

有些客户端只能使用GETPOST这两种方法。服务器必须接受POST模拟其他三个方法(PUTPATCHDELETE)。
这时,客户端发出的 HTTP 请求,要在请求头部加上X-HTTP-Method-Override属性,告诉服务器应该使用哪一个动词,覆盖POST方法。

POST /api/Person/4 HTTP/1.1  
X-HTTP-Method-Override: PUT

1.3 宾语必须是名词,建议复数形式

获取的资源应该是名词,不能是动词。一般来说,资源都是一个集合,推荐复数形式。
比如获取文章的接口,

// 推荐
GET /articles

// 不推荐
GET /article
GET /getArticles
GET /findArticles

1.4 避免多级URL,使用查询字符串

常见的情况是,资源需要多级分类,因此很容易写出多级URL,比如获取某个作者的某一类文章。

GET /authors/12/categories/2

这种 URL 不利于扩展,语义也不明确,往往要想一会,才能明白含义。
更好的做法是,除了第一级,其他级别都用查询字符串表达。

GET /authors/12?categories=2

2.状态码

HTTP的状态码就是一个三位数,分成五个类别。

  • 1xx:相关信息
  • 2xx:操作成功
  • 3xx:重定向
  • 4xx:客户端错误
  • 5xx:服务器错误

服务器应该返回尽可能准确的状态码。这里不展开说明所有的状态码情况。有兴趣的可以 去MDN HTTP响应状态码 看看。

3.服务器回应

3.1 不要返回纯文本

API返回的数据格式,不应该是纯文本,而应该是一个JSON对象,因为这样才能返回标准的结构化数据。所以服务器回应的HTTP头的Content-Type属性要设为application/json。客户端请求时,也要明确告诉服务器,可以接受JSON格式。

3.2 发生错误时,不要返回200状态码

3.3 提供链接

API 的使用者未必知道,URL 是怎么设计的。一个解决方法就是,在回应中,给出相关链接,便于下一步操作。这样的话,用户只要记住一个 URL,就可以发现其他的 URL。这种方法叫做 HATEOAS(全称是Hypermedia as the engine of application state)。
举例来说,GitHub的API都在 api.github.com 这个域名下。访问它,就可以得到其它URL.

github网站运行截图

举例

假设我们在设计一个资源是动物园的api,可以这么设计:

RESTful Api设计

缺点

RESTful Api也存在一些缺点,可以适当了解下。

  1. 比如操作方式繁琐,RESTful API通常根据GET、POST、PUT、DELETE 来区分操作资源的动作,而HTTP Method 本身不可直接见,是隐藏的,而如果将动作放到URL的path上反而清晰可见,更利于团队的理解和交流。
  2. 并且有些浏览器对GET,POST之外的请求支持不太友好,还需要特殊额外的处理。
  3. 过分强调资源,而实际业务API可能有各种需求比较复杂,单单使用资源的增删改查可能并不能有效满足使用需求,强行使用RESTful风格API只会增加开发难度和成本。

拓展·HTTP动词

上面说到HTTP的东西有五种,分别是GET POST PUT PATCH DELETE.但实际上不止这些。
HTTP1.0 定义了三种请求方法: GET, POST 和 HEAD 方法。
HTTP1.1 新增了六种请求方法:OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT 方法。

序号方法描述
1GET请求指定的页面信息,并返回实体主体。
2POST向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST 请求可能会导致新的资源的建立和/或已有资源的修改。
3HEAD类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头
4PUT从客户端向服务器传送的数据取代指定的文档的内容。
5DELETE请求服务器删除指定的页面。
5PATCH是对 PUT 方法的补充,用来对已知资源进行局部更新 。
7OPTIONS允许客户端查看服务器的性能。
8CONNECTHTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。
9TRACE回显服务器收到的请求,主要用于测试或诊断。

但是在我的上一家公司中,只允许使用GET POST 。在做软件的安全扫描时,如果发现使用了GET POST 之外的接口,必须修改掉,也必须限制开放其它方法。
不禁要问,这个是为什么呢?(其实吧,这个是当时面试官问我的,我没回答上来,😭)
其实吧,这是因为涉及到安全的问题。

1.OPTIONS

OPTIONS方法,将会造成服务器信息暴露,如中间件版本、支持的HTTP方法等。

2.PUT

由于PUT方法自身不带验证机制,利用PUT方法即可快捷简单地入侵服务器,上传Webshell或其他恶意文件,从而获取敏感数据或服务器权限。

3.DELETE

利用DELETE方法可以删除服务器上特定的资源文件,造成恶意攻击。

推荐

看完这篇文章之后,还有兴趣的话,可以去 RESTful API 这个站点看看,设计的蛮好的。

网站首页截图

参考资料

1.理解RESTful架构 - 阮一峰的网络日志
2.RESTful API 最佳实践 - 阮一峰的网络日志
3.RESTful API 一种流行的 API 设计风格

完。