我正在着手一个新的网络应用程序,我们想要做它RESTful。现在是时候开始设计交互了,关于REST的基本内容让我感到难过。我试图找出最好的方法来调解REST和OO之间的阻抗不匹配,而不会降低RPC的滑坡。让我给出一个(人为的)例子。
可以创建,修改小部件,然后提交小部件进行审核。
要修改ID为123的窗口小部件,用户会对/ myapp / widget / 123和新窗体数据执行PUT。服务器将所有表单数据重新打包为POJO,并将其交给逻辑层进行验证和后续持久性,调用WidgetManager.update(widgetPojo)。
要提交一个小部件供审阅,用户点击一个按钮,它也会对/ myapp / widget / 123进行PUT,但现在表单数据只有一个字段,状态为“已提交”(我不知道) t再次发送所有表单数据,只是我要更改的字段)。但是,现在服务器需要调用另一个业务对象WidgetStateManager.updateState(123,“submitted”),除了更新状态之外,还要进行其他一些专门的处理。
因此,在尝试使用RESTful时,我已将小部件更新和提交审阅操作建模为PUT到同一URL / myapp / widget / 123。所以现在,在我的服务器端代码中,我需要弄清楚特定PUT请求在业务功能方面意味着什么,以及因此要调用哪些业务功能。
但是,如何通过检查表单数据中的值来可靠地确定要调用的函数? SOOO很容易将“动作”字段与表单数据一起传递,并在PUT中使用“更新”或“提交以供审阅”等值!然后服务器可以根据该值进行切换。但那当然不是RESTful,只不过是装扮成RPC。
仅仅通过在restlet中使用一堆if-then-elses检查表单数据来推断单击哪个按钮似乎不安全或可扩展。我可以想象可以在一个小部件上采取的许多不同的动作,因此有几十个if-then-elses。我在这里错过了什么?我的直觉告诉我,我没有正确建模我的资源,或者我错过了一个有用的特定资源抽象。
答案 0 :(得分:4)
您不仅限于将URL映射到域对象。 RESTful API具有少量操作,但可以应用操作的大量资源。
创建一个小部件:
POST到/ rest / widget(返回“123”)
(“POST方法用于请求源服务器接受请求中包含的实体作为请求行中Request-URI标识的资源的新下属。”
验证小部件123:
POST到/ restapi / validator / 123
(该资源是小部件123的名义“验证器”。)
更新小部件123:
PUT to / restapi / widget / 123
提交小部件123以供审核:
发布到/ restapi / reviewqueue
(只有一个审核队列,因此不需要/ 123。)
删除小部件:
删除/ restapi / widget / 123
答案 1 :(得分:3)
几点;
您的服务公开的资源不必直接实现为代码中的对象。 (服务)接口不是实现。
在进行更新时,您必须提供所有资源状态(您说您只提供更改 - 这是PATCH而不是PUT)。
有时最好将状态更改建模为集合资源。在您的示例中,您确实需要考虑具有关联的“审核队列”的“审核”资源或向窗口小部件添加“需要审核”属性。
方法1.“审核队列”的容器
拥有“评论”对象可以轻松列出小部件以供审核,分配资源以供审核等
GET / review-queue - 列出需要审核的小部件
POST / review-queue - 创建一个新的评论条目(仅列出id,小部件的名称和返回小部件的URL)
DELETE / review-queue / X - 在审核小部件时从队列中删除
如果存在与“审核队列”相关的重要行为,我会使用此方法,例如与添加小部件以供审阅,多个审核队列等相关联的权限
方法2.“需要 - 审核”属性
您可以根据需要决定单独的资源是否过度杀死。您可以使用POST,PUT和GET建模基本功能。
创建窗口小部件时,它的状态包含一个s'需求 - 审查'属性,该属性设置为False。显然你需要POST中的所有外部状态
当窗口小部件需要审核时,请将其删除,然后将其更新为“需求审核”。同样,你需要PUT中的所有外部状态
列出小部件以供审核时使用
GET / widgets /?needs_review = true
你在最后一段中提到了RPC,虽然它不是主题,但我不禁发表评论......
我想也许我们现在全都谴责RPC因为世界的弊病。 RPC的真正问题在于它旨在使远程函数调用对程序员透明,隐藏失败场景并尝试在实现语言中使用等效的远程调用作为标准函数调用。作为一个旧的CORBA(遭遇同样的问题)程序员,我可以理解REST如何纠正失败。
您帖子中的其他要点
如果不检查新状态并将其与现有状态进行比较,则无法确定要调用哪种方法。
在执行任何其他操作之前,您应该验证新状态,并将任何错误传递回提交者。
从你的最后一段开始,我想你已经知道了 - 抱歉。
克里斯
答案 2 :(得分:0)
如果不了解更多有关域名的信息很难说,但拥有“待审核”的收集资源可能是一个好主意。当您的资源流过整个过程时,您可以将它们从一个列表移动到下一个列表。作为附带好处,您还可以选择在这些列表上执行GET,以找出处于该特定状态的资源。