Spring基础篇(5)-restful命名规则

JAVA && Spring && SpringBoot2.x — 学习目录

上来一首打油诗:
动词加名词,名词用复数。
动词分五类,之间可覆盖。
名词若多级,从属或平等。
状态需明确,响应给连接。

1. 什么叫做Restful

简单来讲:Restful是一种框架的规范与约束原则,符合这种规范的架构都是RESTful架构

1.1 RESTful是什么意思?

REST是Representational State transfer (资源)表述性转移。本质上是通过表述完成资源的转移

1.2 RESTful的结构?

RESTful的核心思想就是:客户端发出的数据操作指令都是“动词+宾语”的结构。例如GET /articles这个命令,GET是动词,/articles是宾语。

需要注意的是:根据HTTP规范,动词一律大写。

动词通常来说,其实就是五种HTTP方法,对应CRUD操作。

动词 操作
GET 读取
POST 新建
PUT 更新
PATCH 部分更新
DELETE 删除

作为设计基础,还是需要遵循几个原则的:

  1. 当标准合理的时候遵守标准。
  2. API应该对程序员友好,并且在浏览器地址容易输入。
  3. API应该简单,直观,容易使用的同时优雅。
  4. API应该具有足够的灵活性来支持上层ui。
  5. API设计权衡上述几个原则。
  • GET /tickets #获取ticket列表;
  • GET /tickets/12 #查看某个具体的ticket;
  • POST /tickets #新建一个ticket;
  • PUT /tickets/12 #更新ticket 12;
  • DELETE /tickets/12 #删除ticket 12;

显然从API用户的角度来看,“资源”应该是一个名词。即使在内存数据结构模型和资源已经有了很好的对应,API设计的时候仍然不需要把它们一对一的暴露出来,这里的关键是隐藏内部资源,暴露必须的对外资源。

2. 如何书写RESTful

2.1 动词的覆盖

有些客户端只能使用GETPOST这两种方法,服务器必须接受POST模拟其他三个方法(PUT/PATCH/DELETE)。

这时,客户端发出的HTTP请求,需要加上X-HTTP-Method-Override属性,告诉服务器应该使用哪种动词,覆盖POST方法。

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

上面代码中,X-HTTP-Method-Override指定本次请求的方法是PUT,而不是POST。

2.1 宾语必须是名词

宾语就是API的URL,是Http动词作用的对象,他表述的是一个资源。应该是名词,不应该是动词。

!!!Restful反例

/getAllCars
/createNewCar
/deleteAllRedCars

2.2 宾语是单数还是复数

既然URL是名词,那么应该使用复数,还是单数?

这里没有统一的规定,但是常见的操作是读取一个集合,比如GET /articles(读取所有的文章)这里明显是复数。

为了统一起见,建议都使用复数URL,比如GET /articles/2要好于GET /article/2

2.3 多级的URL的写法

按照Rails中标准定义的方式:

  1. 若定义这个资源的两个参数具有从属关系,那么生成的url就是owner/1/property/1,其中property从属于owner。比如用户1的编号为2的文章,就是users/1/articles/2
  2. 如果两个资源是平等的,那么一般是作为URL中HTTP方法的参数。

举个小栗子

比如汇款动作,从账户1向账户2汇款500元。如何设计URL?
小优同学:POST /accounts/1/transfer/500/to/2
小胖老师:答错了,请坐下。
正确的应该是:将动词转换为名称,(只是一个汇款操作)
即:POST /accounts/transaction?from=1&to=2&amount=500.00

3. 状态码

客户端的每一次请求,服务器都必须给出回应。回应包括HTTP状态码和数据两部分。

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

这五大类共包含了100多种状态码,覆盖了绝大部分可能的情况。每一种状态码都有标准(或者是约定)解释,客户端只需要查看状态码,就可以判断出发生了什么情况,所以服务器应返回尽可能精确的1状态码。

API不需要1xx状态码,下面介绍其他四类状态码的精确含义。

3.1 2xx状态码

虽然200状态码表示操作成功,但是不同的方法可以返回更精确的状态码。

HTTP操作 状态码
GET 200 ok
POST 201 created
PUT 200 ok
PATCH 200 ok
DELETE 204 no content
  • POST返回201状态码,表示生成了新的资源;

  • DELETE返回204状态码,表示资源已经不存在;

  • 202 Accepted状态码表示服务器已经收到请求,但还未进行处理,会在未来再处理,通常用于异步操作。

HTTP/1.1 202 Accepted

{
  "task": {
    "href": "/api/company/job-management/jobs/2130040",
    "id": "2130040"
  }
}

3.2 3xx状态码

API用不到301状态码(永久重定向)和302状态码(暂时重定向,307也是这个含义),因为它们可由应用级别返回,浏览器会直接跳转,API级别可以不考虑这两种情况。

API用到的3xx状态码,主要是303 See Other,表示参考另一个URL。它与302和307含义一样,也是“暂时重定向”,区别在于302和307用于GET请求,而303用于POST、PUT和DELETE请求。收到303以后,浏览器不会自动跳转,会让用户自己决定下一步怎么办,下面是一个例子。

HTTP/1.1 303 See Other
Location: /api/orders/12345

3.3 4xx状态码

4xx状态码表示客户端错误,主要有下面几种。

状态码 含义
400 Bad Request 服务器不理解客户端请求,未做任何处理
401 Unauthorized 用户未提供身份验证凭证,或者没有通过身份验证
403 Forbidden 用户通过身份验证,但没有权限访问请求资源
404 Not Found 所请求资源不存在,或不可用
405 Method Not Allowed 用户已经通过身份验证,但是所用HTTP方法不在权限内
410 Gone 所请求资源已经从这个地址转移,不可再用
415 Unsupported Media Type 客户端要求返回格式不支持。比如API只能返回JSON,但Client要求返回XML
422 Unprocessable Entity 客户端上传附件无法处理,导致请求失败
429 Too Many Request 客户端的请求次数超过限额

3.4 5xx状态码

5xx状态码表示服务端错误,一般来说,API不会像用户透露服务器的详细信息,所以只要两个状态码就够了。

状态码 含义
500 Internal Server Error 客户端请求有效,服务器处理时发生了意外
503 Service Unavailable 客户端无法处理请求,一般用于网站维护状态

4. 服务器回应

4.1 不要返回纯文本

API返回的数据格式,不应该是纯文本,而应该是一个JSON对象,因为这样才能返回标准的结构化数据。所以客户端回应的HTTP头的Content-Type属性要设为application/json

客户端请求时,也要明确告诉服务器,可以接受JSON格式,即请求的HTTP头的ACCEPT属性也要设为application/json

GET /orders/2 HTTP/1.1 
Accept: application/json

4.2 发生错误时,不要返回200错误码

有一种不恰当的做法是,即使发生错误,也返回200状态码,把错误信息放在数据体里面,就像下面这种:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "status": "failure",
  "data": {
    "error": "Expected at least two items in list."
  }
}

上面代码,解析数据体以后,才能得知操作失败。
这种做法实际上是取消了状态码,这是完全不可取的。正确的做法是:状态码反映发生的错误,具体的错误信息放在数据体里面返回。

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "error": "Invalid payoad.",
  "detail": {
     "surname": "This field is required."
  }
}

4.3 提供链接

HATEOAS怎么读(Hypermedia as the engine of application state)超媒体作为应用状态引擎。【“小胖哥哥,你英语翻译太棒了”——小优】

我们知道REST是使用标准的HTTP方法来操作资源的。但仅仅因此就理解成带CURD的WEB数据库架构就太low了吧。这种说法忽略了一个核心的概念,即“超媒体即应用状态引擎(Hypermedia as the engine of application state)”。

超媒体是什么?

当你浏览Web页面的时候,从一个连接跳到一个页面,再从另一个连接跳到另外一个页面,就是利用超媒体的概念:把一个个资源链接起来。

要达到这个目的,就要求在表述表格里面加入链接来引导客户端,在《RESTFul Web Services》一书中,作者把这种具有链接的特性称为“连通性”

RESTful API最好做到HATEOAS,即返回结果中提供链接,连向其他API方法,使得用户不用查询文档,也知道下一步怎么做。比如,用户向api.example.com的根路径发出请求,会得到这样一个文档。

{"link": {
  "rel":   "collection https://www.example.com/zoos",
  "href":  "https://api.example.com/zoos",
  "title": "List of zoos",
  "type":  "application/vnd.yourformat+json"
}}

上面代码表示,文档中有一个link属性,用户读取这个属性就知道下一步调用什么API,rel表示这个API与当前网址的关系(collection关系,并给出该collection的网址),href表示API的路径,title表示API的标题,type表示返回类型。

Hypermedia API的设计被称为HATEOAS。GIThub的API就是这种设计,访问api.github.com就会得到一个所有可用API的网址列表。

HATEOAS实践

那我们就去访问访问https://api.github.com/user这个地址吧。

访问api.github.com/user

参考文章:
restful 接口命名规则

RESTful API 最佳实践

不要被名字吓到-RESTful、HATEOAS、Spring boot之整合

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,045评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,114评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,120评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,902评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,828评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,132评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,590评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,258评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,408评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,335评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,385评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,068评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,660评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,747评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,967评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,406评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,970评论 2 341

推荐阅读更多精彩内容