将 RPC 样式的 Web 服务操作转换为 REST 服务

Posted

技术标签:

【中文标题】将 RPC 样式的 Web 服务操作转换为 REST 服务【英文标题】:Converting RPC style web service operation to a REST service 【发布时间】:2013-01-30 04:37:29 【问题描述】:

我正在使用 ASP.NET Web API 将基于 SOAP 的 RPC 样式“Web 服务”转换为基于 JSON 的 REST Web 服务。 AddXYZ / UpdateXYZ / RemoveXYZ 等方法干净地映射到 POST/PUT/DELETE 的 HTTP 动词。是否有任何最佳实践/指导将典型的 RPC 样式操作(例如“ExecuteXYZ”或“AssignXYZ”样式方法)映射到它的 REST 对应项? 我的看法是,此类操作将映射到相应的 URL 可寻址资源,例如“ExecuteXYZRequest”和“AssignXYZRequest”

http://myhost/myservice/ExecuteXYZRequest
http://myhost/myservice/AssignXYZRequest

执行“ExecuteXYZ”的请求将转换为 POST 操作。

获取提交的请求将转换为 GET(通常用于获取提交的请求的状态)。

http://myhost/myservice/ExecuteXYZRequest/1   <--- 1 is the ID of the request

取消请求(假设它是可取消的)将转换为 DELETE

POST 不会真正映射到任何东西。

以上听起来像是一个合理的 REST 实现,还是我完全不在乎我的想法? 非常感谢您的想法/指导。

更新 这是我要建模的具体示例: 联系人和事件实体之间的多对多关系。将联系人的成员资格建模为 REST 资源的最佳方法是什么,以便可以从事件中添加/删除联系人。在 RPC 领域,这将是诸如“AssignContactToEvent”之类的方法,它获取两个实体的 ID 并建立这两者之间的关系。如何在 REST 中自然地将其建模为资源。我记得有一个链接和“rel”的概念,但找不到具体的实际示例来说明如何使用 Web API 对这样的东西进行建模

【问题讨论】:

【参考方案1】:

问题是 RPC 方法映射到 REST 是否有意义 帖子中指出的资源

简而言之;不,以您描述的方式将方法映射到资源是没有意义的:)

为了成功“做 REST”,我们必须换个思路,摒弃 RPC 和 CRUD 操作的所有想法;一旦你接受了 RESTful,这些真的是相当有限的!

REST 中信息的关键抽象是资源。任何 可以命名的信息可以是资源:文档或图像, 临时服务(例如“洛杉矶今天的天气”), 其他资源的集合,一个非虚拟对象(例如一个人), 等等。换句话说,任何可能成为目标的概念 作者的超文本参考必须符合 a 的定义 资源。资源是到一组实体的概念映射,而不是 对应于映射中任何特定点的实体 时间。 http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm

然后,方法或动作/动词就不是资源,因此它在 URI 中没有位置——当然,除非您正在构建一个允许人们创建自己的方法的应用程序,这将是相当不寻常的!

以您的联系人和事件关系的具体示例,重要的是要了解您的“AssignContactToEvent”是在 Web-API 层下发生的操作,不能以 REST 方式建模;我希望这将在以下示例的过程中变得清晰:)

首先,我们需要一些好的资源来为所有联系人列表和所有事件列表建模:

/contacts

/events

这些资源对由 ID 令牌标识的单个联系人或事件建模:

/contacts/contact_id

/events/event_id

您的应用程序的用户想知道谁参与了特定事件,因此我们需要一个资源来模拟事件参与者的列表:

/events/event_id/participants

当我们想要将联系人添加到事件时,我们可以将最小的联系人表示(仅包含联系人 ID)发布到事件的参与者列表:

POST /events/event_id/participants/ HTTP/1.1
Content-Type: application/json

'id': contact_id

从事件中删除联系人:

DELETE /events/event_id/participants/contact_id HTTP/1.1

您的应用程序用户还希望对联系人参与的事件一目了然,因此您需要另一个资源来对此进行建模:

/contacts/contact_id/events

同样,您现在可以获取联系人的事件列表,并使用 POST 分配事件:

POST /contacts/contact_id/events/ HTTP/1.1
Content-Type: application/json

'id': event_id

重要的一点是,每当您需要对新事物进行建模时,您都需要创建资源。如何存储数据对象的属性和关系的细节在 Web-API 后面被抽象出来。事实上,数据存储技术将来可能会发生变化,比如从关系存储到对象存储,或者您更改编程语言或框架,但在所有情况下,您的 URI(和 Web-API)都保持不变。 REST 和 HTTP 旨在超越底层运行的技术。

作为创建新资源的最后一个示例,考虑一个模拟具有组织者角色的联系人列表的资源:

/events/event_id/organisers

或者这个模拟联系人正在组织的事件列表的模型:

/contacts/contact_id/events-organised

如果您有身份验证系统,那么您可能希望查看正在参加的活动:

/my-account/events

我希望这有助于阐明 Web-API 的目的并遵循 ​​RESTful 原则。

【讨论】:

@simony- 感谢您的全面回答。我得到了您为 CustomerRequests 引用的示例,但是您将如何“重新设计”或“重新思考”对 REST 样式编程模型执行处理操作的 RPC 方法(例如我上面列出的方法)?查看“gorodinski.com/blog/2012/07/13/…”,作者在其中创建了一个“ImportController”来表示一个导入过程,该过程是一个 REST Uri 可寻址资源。 没问题 :) 我简单地提到过,我给出的简单示例也可能适用于长时间运行/后台任务的管理,您参考的文章在一定程度上涉及到这一点。您能否澄清您的问题以更具体地描述您要实现的目标,并提供您尝试解决的问题的实际示例。您的应用程序是做什么的? 这是一个我想建模的例子。联系人和事件实体之间的多对多关系。将联系人的成员资格建模为 REST 资源的最佳方法是什么,以便可以从事件中添加/删除联系人。在 RPC 领域,您将有一个方法获取两个实体的 ID 并设置这两者之间的关系。如何在 REST 中自然地将其建模为资源? 我很乐意为您描述这一点。首先,请您编辑您的问题以反映此示例,以便我可以在回答中包含描述。我之前的回答是为了回应您的澄清“我知道。问题是 RPC 方法映射到帖子中指出的 REST 资源是否有意义?”。我的简单回答是“不” :) 如果您仍然想了解后台任务,您也可以提供一个示例。 感谢详细的解释和解答【参考方案2】:

目前我见过两种方法。

一个是如果动作很少,则将动作映射到动词,因此不会发生冲突。因此,如果 action 不安全也不幂等则POST,否则如果不安全但幂等则PUT

POST http://myhost/myservice/XYZ

其他是将动作定义为逻辑资源:

POST http://myhost/myservice/XYZ/Assignment

后来更富有,我赞成。

【讨论】:

这就是我的倾向。为了更进一步,通过可以对资源执行的操作来限定资源可能是有意义的。如:myhost/myservice/Contacts/Import或myhost/myservice/Contacts/1/ChangeOwnership @AbhijeetPatel 好吧,我说的是我从 REST 社区得到的东西。所以这是目前的做法。【参考方案3】:

几个重点

RPC 端点 -> REST 入口点

RPC 读取方法 -> REST GET on Resource

RPC 创建方法 -> REST POST 操作

PRC删除方法->REST DELETE操作

RPC SOAP 消息 -> REST PayLoad

additonaly,想想 Cache headers , Content-Type headers 比如@Consumes,@Produces

【讨论】:

@TechExchange-“RPC 端点 -> REST 入口点”。如果我正确地解释了这一点,那么 RPC 方法 = 一个 REST 可寻址资源,如我的帖子中所示的示例中所述。这准确吗? @TechExchange- 好的。我提到的方法对应到什么? 就像我上面提到的,POST 总是创建 我知道。问题是 RPC 方法映射到帖子中指出的 REST 资源是否有意义 是的,如果您不确定,也可以逐步进行。

以上是关于将 RPC 样式的 Web 服务操作转换为 REST 服务的主要内容,如果未能解决你的问题,请参考以下文章

Axis2 的 wsdl2java 在 RPC/Encoded 样式 Web 服务上失败

将 HATEOAS 用于 RPC 样式的命令是不是是 RESTful

Odoo Web Service API

Odoo Web Service API

为啥 SoapClient 在文档/文字样式中使用 WSDL 返回带有额外关键元素的数组?

一句话读懂RESTful