文档章节

RESTFul

sheepbao
 sheepbao
发布于 2017/08/24 16:42
字数 1566
阅读 21
收藏 0

参考:

REST 本身只是一种架构风格,并非具体标准,但 HTTP 可以认为是一份可参考的标准。正确的理解和应用的 HTTP 协议是该架构风格的一种实现,简单理解就是:HTTP 用 URI 实现了 REST 的关键概念“资源”;用 GET/POST/PUT/PATCH/DELETE 等 METHOD 实现了 REST 的另一个关键的统一接口的操作;用 status code 表示操作的结果。

当前的 RESTful API 实现 JSON over HTTP 占绝对优势地位, 若沟通中出现“REST标准”,一般指的就是这种实现。

HTTP 中的 URI 是一个树形的设计,有无限的逻辑扩展性。而 REST 本身又强调服务器是“无状态”的,正确设计的情况下,也可以带来近乎无限的物理扩展性(主要指水平扩展)。

资源是一个实体或者实体的集合(也是实体),每一种资源都有唯一并且和其它资源以相同原则组织的 URI 来标识,这个 URI 也叫 endpoint,然后在资源上使用统一的方法表达各种操作,如 POST 只是创建新资源不能用来获取资源。

如何抽象资源是业务规划的关键第一步,对业务的建模决定了我们如何看待数据、运行时模块和对它们的操作。此处的关键是:对业务的理解,开发能力和设计能力。应适当的结合并应用面向对象原则,但不宜过度。此处非常关键,这阶段的设计应有多人确认可行性。

良好抽象的资源应该是有明确而不是模棱两可定义的 URI,对 URI 定义有不易理解的部分要多加斟酌。URI 定义中的字符分割,推荐用“减号”而非下划线。

插曲:MVCC(多版本并发控制),指同一个数据实体有多个版本之别,当读时返回当前最新的版本,当有写入请求时版本更新。在读多写少的场景下,可以比全局锁等手段提升性能。唯一的冲突发生在多个并发写入请求时:A读(ver=1)-B读(ver=1)-A写(ver1->ver2)-B写(失败,它想修改的是ver1,但现在已经是ver2)。

插曲:幂等性,类似于分布式一致性的概念,可参考 http://www.cnblogs.com/weidagang2046/archive/2011/06/04/idempotence.html

METHOD 完整定义参考:Method Definitions http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html,一般我们只使用五种 METHOD :

  • GET :从服务器获取资源或者资源的集合,只读,幂等,无副作用。
  • POST :在服务器新建一个资源,只写,有副作用,会改变资源集合。
  • PUT :使用客户端数据在服务器覆盖式更新资源,并发场景建议使用 MVCC 保证一致性。
  • PATCH :客户端提供部分数据,在服务器更新资源的一部分数据,同样建议在并发场景使用 MVCC 保证一致性。
  • DELETE :从服务器删除资源,可选使用 MVCC。

使用正确的方法做正确的操作是容易在实现上忽略的一点,在开发过程中务必检查方法的正确性,防止一个 GET 走天下的实现。

API 实现的动作必须由 METHOD 字段体现,而不能在 URI 中体现,简单的说:URI 里尽量不要出现动词。如下是大忌:

  • GET /api/v1/create-entity?id=123&name=obc
  • POST /api/v1/get-entity?id=123

正确的设计应该是:

  • POST /api/v1/module/entity?name=obc&unique
  • GET /api/v1/module/entity/123

整体 API 的实现包括 JSON 结构定义,可读性是第一要素,尽量做到自释义。整体设计追求使用者能以最低的脑力代价无岐义的理解资源、属性、操作、分类、条件、结果等。若有可能尽量避免使用整形表达状态或类型,如type:1改成type:"udp",result:0应改成result:"success"。

若我们有一个消息服务可以这样设计:

新建一个消息,新的消息是一个资源,会有一个唯一标识。dest/clientuuid参数表示目标和客户端ID,客户端ID的作用是在重试的时候实现服务器的无状态需求:相同CID的请求被认为是重复发送,若上次已经成功执行,则不再执行动作直接返回结果。此处只接受 POST 命令,意为在消息这个集合上的操作,只有新加入。若要执行删除等操作,必须针对具体的单个消息。

  • POST /api/v1/messages?dest=DEST&clientuuid=CID

获取/修改/删除 一条标识为 123456 的消息,此处消息用整形数字来标识。该消息在执行 GET 时可以通过 version 参数指定获取不同的版本。在执行修改和删除动作时,version 用来实现 MVCC 以保证幂等性。

  • GET | PATCH | DELETE /api/v1/messages/123456?version=VERSION

也是新建一个消息,不同的是只发给某个用户 uid666。令牌机制(token)也是一种防止重复请求的方法,但这个 TOKEN 是服务器下发的并非客户端自己生成。可以参考:https://6xiao.github.io/2017/0122.token.html

  • POST /api/v1/user/uid666/messages?token=xxxxxxxxxxx

获取某个用户的私信消息列表,参数指定开始位置和获取数量,比分页设计更容易实现服务器的无状态化。

  • GET /api/v1/user/uid666/private?last=LASTID&count=COUNT

当执行完操作后,服务器务必返回能正确表达结果的状态码,若有错误需要在结果 JSON 中说明。常用状态码如:

  • 200 :成功
  • 201 :新资源创建成功
  • 304 :资源未更改
  • 400 :请求中的路径、参数或者其它错误
  • 404 :资源不存在
  • 500 :服务器内部错误,应该在返回的 JSON 中表达原因。

特定的状态码必须和实际情况一致,同样要避免一个 200 走天下。STATUS CODE 完整定义参考:Status Code Definitions http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

© 著作权归作者所有

sheepbao

sheepbao

粉丝 7
博文 18
码字总数 16873
作品 1
深圳
后端工程师
私信 提问
【用jersey构建REST服务】系列文章

1.用Jersey构建RESTful服务1--HelloWorldhttp://www.waylau.com/jersey-restful-helloworld/2.用Jersey构建RESTful服务2--JAVA对象转成XML输出http://www.waylau.com/jersey-restful-java-x......

waylau
2014/08/23
1K
1
对restful的一些疑问

现在整天都可以看到restful,restful,restful,restful,restful。但是我确有很大的疑问,希望有人解答一下。restful说请求都用GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE这7中请...

仁江
2016/01/19
443
6
REST 风格的Web 架构与HTTP协议区别

以前学习过RESTFUL 的一些内容,在实践中发现RESTFUL 的Web 架构和HTTP 协议很类似,有点傻傻都分不清楚的感觉。例如,凭什么说我自己的web服务 是 RESTFUL 架构呢,而不是一个普通的HTTP 产...

水稻
2015/03/13
1K
0
Practical guide to WCF RESTful service

REST (Representational State Transfer) is an architectural style that dictates to think in terms of resources and their representation instead of just thinking about methods wit......

东风125
2015/10/26
22
0
RESTful - 收藏集 - 掘金

远程接口设计经验分享 - 后端 - 掘金 写在前边 分布式架构是互联网应用的基础架构,很多新人入职以来就开始负责编写和调用阿里的各种远程接口。但如同结婚一般,用对一个正确的接口就如同嫁一...

掘金官方
2017/05/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

js如何控制table中的某一行动态置顶

两行代码搞定: $('#'+item.roadCode).fadeOut().fadeIn();//获取到需要置顶的行 $(".table").prepend($('#'+item.roadCode)); 其中,fadeOut()方法 作用 --- 从可见到隐藏 如下: prepend(......

码妞
58分钟前
4
0
四种解决Nginx出现403 forbidden 报错的方法

我是在在本地用虚拟机中通过yum安装nginx的,安装一切正常,但是访问时报403, 于是查看nginx日志,路径为/var/log/nginx/error.log。打开日志发现报错Permission denied,详细报错如下: 1....

dragon_tech
今天
3
0
获取RestResultResponse返回的值

Springboot项目,需要调其他服务的接口,返回值类型是RestResultResponse 打断点的结果集是这个 打印出来的getData(): [{id=3336b624-8474-4dd9-bd5b-c7358687c877, paraNo=104, para=Postpo...

栾小糖
今天
4
0
【小学】 生成10以内的加减法

#!/usr/bin/env python# coding: utf-8from random import randrange# 题目的最大数值R_MAX = 10# 生成的题目的数量R_PAGE = 70# 生成减法列表def get_sub_list():...

Tensor丨思悟
今天
11
0
JavaScript设计模式——适配器模式

  适配器模式是设计模式行为型模式中的一种模式;   定义:   适配器用来解决两个已有接口之间不匹配的问题,它并不需要考虑接口是如何实现,也不用考虑将来该如何修改;适配器不需要修...

有梦想的咸鱼前端
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部