1

2000年的时候,Douglas Crockford声明JavaScript是最被误解的编程语言。这种误解来源于不良的命名规范,错误设计,非标准模式等等。因此,误解几乎是与之俱来的。

我也在关于Restful架构上发表了一个相似的意见:REST是世界上被误解最严重的架构模式。

事实上,大多人认为,创建一个RESTful API只需要基于URL和HTTP动词。这是完全错误的。

这个误解存在太久了。但是和JavaScript不同,REST规范讲述的非常清晰。它的命名本身就强调了状态的转化,但是这个概念却是所谓的RESTful API设计者们所最为忽视的。

如果你随便问十个开发者,他们的API是否支持HATEOAS,至少九个人会睁大双眼回答:你到底在说啥?

clipboard.png

REST名字本身已经解释的很清楚了。REST并没有指定使用的协议以及如何标记一个资源。它强调的是表现层状态转移。就像Roy Fielding所强调的,对于一个被称作RESTful的API来说,状态转移管理是一个必须要完成的需求。

一个真正的RESTful API会提供给客户端一个新的状态,以及切换到后序状态的方法。它提供了资源的表示(不一定用JSON的形式)和指向别的资源的富链接,如下所示:


{
  "id": 463219,
  "firstName": "John",
  "lastName": "Smith",
  "company": "Acme Inc.",
  "salary": 72500,
  "links": [
    {
      "href": "https://api.myapp.com/employees/employee/463219",
      "rel": "self"
    },
    {
      "href": "https://api.myapp.com/companies/company/375",
      "rel": "company"
    },
    {
      "href": "https://api.myapp.com/payments/employee/463219",
      "rel": "payments"
    }
    ]
}

这里的资源进行自我描述之后,提供了相关资源的链接。

不管你是使用HTTP协议还是其它的,REST方法的关键点在于由服务器进行客户状态的转化。客户端的状态几乎完全是由服务器进行转化的。因此,API的版本也有其存在的意义。客户对于RESTful接口的了解仅限于入口点。其它的应该从解析服务器的响应来获取。这个场景很少有应用能够实现。

单纯的根据HTTP动词进行CRUD操作的API和状态转换没有任何关系。你可以将其称为WEB API或是HTTP API,但是请不要把它叫做RESTful。


词汇补充

HATEOAS: Hypermedia As The Engine Of Application State
客户端和服务端完全通过超媒体进行交互。REST客户端只需要对超媒体有一定的了解,无需知道别的信息。
REST客户端从一个简单且固定的URL进入REST应用。客户端之后所做的任何操作都通过服务器返回的资源决定。

比如,你发出这样一个HTTP请求,试图获取账号为12345的信息:

GET /accounts/12345 HTTP/1.1
Host: bank.example.com
Accept: application/xml
...

得到的响应是一个XML形式的信息如下:

HTTP/1.1 200 OK
Content-Type: application/xml
Content-Length: ...

<?xml version="1.0"?>
<account>
    <account_number>12345</account_number>
    <balance currency="usd">100.00</balance>
    <link rel="deposit" href="https://bank.example.com/accounts/12345/deposit" />
    <link rel="withdraw" href="https://bank.example.com/accounts/12345/withdraw" /> 
    <link rel="transfer" href="https://bank.example.com/accounts/12345/transfer" />
    <link rel="close" href="https://bank.example.com/accounts/12345/close" />
</account>

这个响应包含了所有可能的状态转化连接,如存款,取款,转账或是关闭账户

当检索到该账户透支时,会返回如下信息:

HTTP/1.1 200 OK
Content-Type: application/xml
Content-Length: ...

<?xml version="1.0"?>
<account>
    <account_number>12345</account_number>
    <balance currency="usd">-25.00</balance>
    <link rel="deposit" href="https://bank.example.com/account/12345/deposit" />
</account>

现在只剩下一个可用链接:存钱。其它的链接都将不可用。

clipboard.png
想要了解更多开发技术,面试教程以及互联网公司内推,欢迎关注我的微信公众号!将会不定期的发放福利哦~


raledong
2.7k 声望2k 粉丝

心怀远方,负重前行