10 月 23 - 25 日,QCon 上海站即将召开,现在购票,享9折优惠 了解详情
写点什么

在 RESTful 服务中实现部分更新

  • 2010-12-06
  • 本文字数:1915 字

    阅读完需:约 6 分钟

近期 Alex Scordellis 发表了一篇文章,文章主题是如何针对客户端与 RESTFul 服务的交互进行建模和设计,实现部分资源的更新。

[在 REST In Practice (由 Ian Robinson Jim Webber Savas Parastatidis 合著)这本书中] 有个问题很让我困扰,作者们推荐使用 POST 方式更新资源的状态。这是根据对 PUT 语义的解释做出的选择。根据 HTTP 规范的描述:

如果请求的 URI 指向已经存在的资源,那么封装的实体应该被视为驻留在原始服务器上实体的修改后的版本。

在这本书里,作者们对此的解释是,在同一个 URI 里,PUT 请求封装的正文(body)中应该包含与 GET 请求的表现形式相同的元素。由于我们正在使用 HATEOAS 风格,表现形式包括链接和其他超媒体表现形式。其含义就是客户端 PUT 的内容应该同时包含业务数据(例如咖啡订单的新内容)和超媒体控件(工作流程中的下一个有效步骤)。

Alex 的观点是服务的超媒体和资源展现形式应该驱动客户端的工作流,并且他提出了四种可能的方法针对这种交互方式进行建模。其中一些例子可以从 RESTBucks 的文章里找到。

使用 PATCH […] 这种方式没有得到广泛的支持。我也觉得它语义上存在问题。从客户的角度来看,业务数据组成的订单(多少杯拿铁?)就是整个资源。客户并不会把这种方式看做是 PATCH,而会看做是替换,例如 PUT。PATCH 对于阐述像“在拿铁中放脱脂牛奶,而不是我原来定的全脂牛奶”这样的场景才有意义。 使用 POST 这种方法是书中推荐的。对我来说,它与 PATCH 有类似的问题。POST 意味着追加资源。在咖啡订单资源里 POST 一杯卡布奇诺,感觉就像追加了一杯卡布奇诺,而不是用卡布奇诺替换原有咖啡订单。 使用 PUT,包含超媒体 如果遵循严格的解释,PUT 应该包括整个展现形式,客户端同时发送完整新咖啡订单和所有的超媒体控件。
使用 PUT,不包含超媒体 客户端发送新订单的完整展现形式,但没有链接。我觉的这个概念是对的。客户端通过发送可用的部分数据的完整表现形式来满足 PUT 的需要,但并不负责哪些超媒体控件是有效的。

经过与 @serialseb @iansrobinson @jimwebber 讨论之后,Alex 总结了以下规则,这也满足了 PUT 作为动词语义的期望。

针对 GET 请求的响应,服务提供现有状态的完整表现形式,包括业务数据和有效的超媒体控件。客户端 PUT 由其负责的那部分数据的完整展现形式。

针对这一讨论,William Vambenepe补充了其他需要注意的事项

我们来举个简单的例子。如果一个元素没有在部分更新中描述,这意味着什么?是明确的删除动作,表示在展现形式中删除该元素?或表示“不要改变其当前值”。如果是后者的话,我怎么做删除操作呢?是需要部分 DELETE,就像部分 PUT 一样?我希望不是,否则必须要有一种机制来实现类似 PUT 的部分删除元素。空值?这和并不存在的元素不是一回事。Nil 值?那么我如何在 JSON 中处理它呢?

他声称,设计部分资源更新是个十分困难的问题,现在正试图通过规范解决,例如 WSDM、WS-Management 和 WS-ResourceTransfer。

好消息是我们已经犯了很多错,而且已经得到了很多经验教训(参阅 technical rant post-mortem experiment )。坏消息是有大量的新的错误还在等待着我们。

Stu Charlton 同样对这个问题抱有疑惑,而且他指出了这样一个事实,RESTFul 超媒体不能真正描述数据模型。据他而言,RESTful 服务要想具备更好的交互能力,还需要做以下两件事:

(a)[封闭的] 数据模型覆盖 80% 的公共用例,可以基于 JSON 和 XML 格式进行描述。

(b) 多媒体类型覆盖 80% 的公共用例,用来描述资源的生命周期和状态转移──换句话说,就是让 POST 在超媒体中实现自描述。因为计算机的世界不仅仅是更新数据,更多是关于抽象的描述。

针对 Alex 发表的文章的评论:

你应该具备 / 两种 / 资源:客户端的订单告诉服务器它想要什么,服务端的“票据”负责与客户端确认详细信息──增加任何其需要的附加数据、链接等。服务端的票据依赖于客户端的订单,包括在订单执行过程中任何内外部流程的状态。但谁来提供客户订单呢?当然是客户端!那么,除非你有一个不对称的设置,在这种情况下,客户端可以 POST 和 / 或 PUT 它的订单到服务器的某处。现在客户端可以一次性提交和改变 / 整个 / 订单资源,不需要担心任何服务端产生的数据。

有很多提议用来解决这一问题,而且,如果能够对资源进行恰当的建模,这个问题似乎可以很容易解决。很多时候会考虑到,把资源作为实体来支持 CRUD 操作也是同样的问题,只有把建模的资源作为“资源”和提供的服务,就像在 Duncan Craggs 示例中一样,才是解决问题的方案。不过更大的问题是如何让所有人都同意这个方案。请仔细阅读初始文章评论,并分享你的观点。

查看英文原文: Implementing Partial Updates In RESTful Services

2010-12-06 09:134209

评论

发布
暂无评论
发现更多内容

为什么生命科学企业都在陆续上云?

阿里云弹性计算

HPC 高性能计算 生命科学 基因测序

我国SaaS产业的发展趋势与路径

小炮

建木持续集成平台v2.5.0发布

Jianmu

开源 DevOps CI/CD Worker 建木CI

一文理解OpenStack网络

华为云开发者联盟

后端 网络

TDengine可通过数据同步工具 DataX读写

TDengine

数据库 tdengine 时序数据库 DataX

AntDB数据库在线培训开课啦!更灵活、更专业、更丰富

亚信AntDB数据库

数据库 AntDB 培训学习 数据库·

《各行业零代码企业应用案例集锦》正式发布

明道云

架构实战营 第 6 期 毕业总结

火钳刘明

如何化解35岁危机?华为云数据库首席架构师20年技术经验分享

华为云开发者联盟

中年危机 经验分享 华为云

Datakit 代理实现局域网数据统一汇聚

观测云

升哲科技 AI 智能防溺水服务上线

SENSORO

大数据 AI 物联网

畅直播|针对直播痛点的关键技术解析

ZEGO即构

直播体验升级 首帧秒开

Redis+Caffeine两级缓存,让访问速度纵享丝滑

码农参上

redis 缓存 JAVA开发 Caffeine

面试官:你说你精通Redis,你看过持久化的配置吗?

阿Q说代码

redis aof rdb 数据持久化

海泰前沿技术|隐私计算技术在医疗数据保护中的应用

电子信息发烧客

如何抓手机的包进行分析,Fiddler神器或许能帮到您!

wljslmz

抓包 fiddler 6月月更

共享洗车机多少钱一台?看品牌

共享电单车厂家

自助洗车机价格 自助洗车加盟 共享洗车机多少钱

车白兔:洗车新模式共享自助洗车

共享电单车厂家

自助洗车 自助洗车加盟 车白兔洗车

如何做到全彩户外LED显示屏节能环保

Dylan

LED显示屏 全彩LED显示屏 户外LED显示屏

XTransfer技术新人进阶秘诀:不可错过的宝藏Mentor

XTransfer技术

职场新人 职场经验

主数据建设的背景

奔向架构师

数据仓库 主数据 6月月更

在shiro基础上整合jwt,可在项目中直接使用呦

阿Q说代码

springboot Java EE 权限验证 shiro整合jwt

心楼:华为运动健康的七年筑造之旅

脑极体

牛客java选择题每日打卡Day1

京与旧铺

6月月更

Volcano成Spark默认batch调度器

华为云开发者联盟

云计算 数据分析 后端

即构「畅直播」上线!提供全链路升级的一站式直播服务

ZEGO即构

应用实践 | 海量数据,秒级分析!Flink+Doris 构建实时数仓方案

SelectDB

数据库 flink 数据分析 Doris 数仓

架构实战营 第 6 期 毕业设计

火钳刘明

#架构实战营 「架构实战营」

Guava中这些Map的骚操作,让我的代码量减少了50%

码农参上

JAVA开发 Guava java工具包

优酷 Android 包瘦身治理思路全解

阿里巴巴文娱技术

治理 包大小

openGauss内核:简单查询的执行

华为云开发者联盟

数据库 互联网 华为云

在RESTful服务中实现部分更新_SOA_Dilip Krishnan_InfoQ精选文章