【问题标题】:REST design: what verb and resource name to use for a filtering serviceREST 设计:过滤服务使用什么动词和资源名称
【发布时间】:2012-11-04 07:47:12
【问题描述】:

我正在开发一个清理/过滤服务,它有一个方法接收在 xml 中序列化的对象列表,并应用一些过滤规则来返回这些对象的子集。

  1. 在 REST-ful 服务中,我应该为这种方法使用什么动词?我认为 GET 是一个自然的选择,但我必须将序列化的 XML 放在请求的正文中,这有效但感觉不正确。其他动词似乎不符合语义。

  2. 定义该服务接口的好方法是什么?将资源命名为 /Cleanup 或 /Filter 似乎很奇怪,主要是因为在我在网上看到的示例中,它始终是一个名称,而不是用于资源名称的动词。

  3. 我是否认为 REST 服务更适合 CRUD 操作,而您在这种服务的情况下开始违反规则?如果是,那么我是否做出了错误的架构选择。

  4. 1234563要么选择不应该使用的 REST,要么可能会过度思考一些无关紧要的东西?在这种情况下,真正重要的是什么?

【问题讨论】:

  • 您能否提供一些示例或至少一些稻草人网址,以便我们更好地了解您要完成的工作?
  • 我在问题中的描述还不够:“我正在开发一个清理/过滤服务,它有一个方法可以接收在 xml 中序列化的对象列表,并应用一些过滤规则来返回那些对象。”
  • 否 - 您的方法是过滤和返回数据(意味着获取),还是过滤和清理和改变服务器上的资源(可能意味着删除或 POST 动词取决于)。
  • 有什么帮助是传递数据的示例(不管 REST 等...),服务器端完成了哪些工作/修改以及预期返回给客户端的内容 - 实际数据流示例。
  • 它不会影响服务器上的任何资源,它只是对传递给它的对象列表进行清理,主要是现在消除重复,将来可以做更多,但它会永远不要改变服务器上的资源。

标签: http rest webserver restful-architecture


【解决方案1】:

REST 就是按照设计的方式使用 HTTP。考虑 RESTful(标题是 REST 设计 :):

  • URL 应该是资源的永久链接(缓存优势、存储/共享端点等...)
  • 由于它们是资源的永久链接,因此 URL 中有动词暗示您走错了路径(过滤器是动词)。
  • 资源集合可以是端点 /foos。
  • 如果您想过滤资源集合,请考虑查询字符串参数,例如 ?filter= 或类似 ?ids=1,2,3,4,5 的参数。
  • GET 不应更改资源。请注意,“清理”意味着某些内容将被删除,因此在执行 GET 时要小心更改资源。 REST 说 GET 不应该改变资源。想象一下缓存服务器将您的清理请求作为 GET 并返回 OK,因为 t 已缓存。缓存服务器知道不缓存 POST、DELETE 等...(这就是 HTTP 的设计方式)。
  • 不排除多次​​调用 - 例如,您可能会执行 get 过滤并获取一组资源进行清理,然后可能会执行多个或一个 DELETE 动词调用来进行清理。
  • 有时有一个时间资源,如事务或“工作”,可以像清理工作一样工作。不要排除对包含要清理的项目的主体的资源的 POST 并返回作业 ID。然后,您可以查询 jobid 以了解清理进度或状态。

很难给出确切的指导,因为问题并不明确,但希望上面的 RESTful 原则指导和想法能让您走上正轨。如果您澄清了确切的调用,我会尝试并推荐 API。

所以,假设您想清理重复的 foo。

[GET] /foos/duplicates(或 /foos?filter=duplicates)

返回一个带有重复标识的 foo 的主体。假设返回 1,2,5(可能是名称)。

那么你可以发出:

[DELETE] /foos 的主体是一个包含 1,2,5(或名称,如果唯一)的数组。删除调用是被动的,所以即使 GET 调用根据 REST 原则被缓存也没关系。

不走 REST 路由(例如 POX 或 JOSN RPC over http)也是可能且有效的,但此时要意识到它不是 REST。这很好,但您并没有得到 fielding 论文中描述的 REST 的好处。

http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm

另外,请阅读:

http://blog.steveklabnik.com/posts/2011-07-03-nobody-understands-rest-or-http

编辑:

在阅读了您澄清的评论后,您将向服务器发送一组对象(不是持久的服务器端),并返回过滤掉欺骗的子集(如服务器端辅助函数),一些选项是:

  1. 如果可能的话,做这个客户端/浏览器端 - 为什么要使用网络往返来过滤掉收集中的欺骗?
  2. 如果由于某种原因只有服务器有特定的知识/数据来确定两个项目在功能上是等效的(即使数据不完全相同),那么考虑将数据集发布到服务器,响应正文包含唯一/过滤集。即使服务器没有持久化该集合,它也会落入一个“临时”对象或集合中,并且服务器正在修改它。从概念上讲,它不是服务器资源的 GET,缓存在这种情况下没有任何好处。

【讨论】:

  • 谢谢 bryan,再多陪我一点,快到了 :) 你的 Foos 示例很好,问题是 Foos - 在我的情况下 - 本身并不存在,它们只是任何东西在请求的主体中传递(这就是为什么我说它就像一个辅助方法,作用于它的参数并且没有其他副作用,即使参数是按值传递的)。可能是我没有正确获取“资源”,您是否认为请求正文中传递的 Foos 是资源?它们不会在任何地方持久化,并且对 GET /Foos 的调用不会返回任何内容,它们只是传递给函数的内容。
  • 假设我的示例是对 foo 进行排序的方法,您在请求正文中传递一些 foo,它们根据某些规则进行排序并传回。但是你不能做一个 GET /Foos 因为除了在请求正文的上下文中它们不存在。您将如何设计 API 来执行这种排序?
  • 好的,刚刚看到编辑......它正在执行服务器之旅,因为重复数据删除的一些规则涉及检查客户端不可用的其他外部资源,所以我猜你的 #2 回答了我的问题。只是确认一下,不持久化数据时POST不违反REST原则?
  • 这是一种解释,但那时它是一个时间对象。 REST 明智地将其存储在内存中以执行过滤器或将其保存在文件/数据库中,过滤它,然后返回它没有区别。时间对象的经典示例是工作或事务——它是短暂的。您的过滤器请求本质上是您推迟到服务器的临时工作。
【解决方案2】:

最后一个问题:真正重要的是以一种正确的方式完成工作

  • 正确
  • 实用又好用
  • 未来的程序员(可能包括您自己)可以轻松维护

REST 非常适合对资源进行操作,其中每个 URL 都匹配一些可以操作的对象。它不太适合其他用途,但这些是比实际规则更多的指导。其他人已经指出了原始的dissertation on REST,但值得记住的是,很少有实现是纯的。

如果您有多个 URL 执行这些转换类型的功能,请考虑将它们放在自己的特殊 URL 空间中,例如 /api/filter/api/transliterate 等。这将帮助用户和维护者知道某些 URL 't REST,但更像远程过程调用。将数据发布到这些 URL 会导致您返回某种数据。

如果您对特定的名字感到困惑,您应该列出候选人名单,喝几杯啤酒,然后从名单中选择一个。当我卡在细节上时,我就是这样做的。

SOAP 是一个简洁的协议并且有它的用途,但它往往非常繁重。与使用任何特定技术相比,良好的文档和一致性对于您萌芽的 API 可能更为重要。

【讨论】:

  • REST 论文超出了上面的要点。 (也许正确的是一个包罗万象的)。但是 REST 的一个关键点是缓存和永久链接。您打破 REST 概念的一个迹象是,您的 URL 中是否包含诸如“过滤器”之类的动词。 URL 应该引用永久链接引用,如果你开始妥协,你最终只会得到 POX。
  • +1 为您的命名过程...那么使用哪个动词呢?
  • @bryanmac 那么在这种情况下,REST 是一个错误的选择,还是有办法将我的资源命名为更符合 REST 风格?
  • transform 和 filter 都是 URL 中的动词 - 它是伪装成 REST 的 RPC。
猜你喜欢
  • 1970-01-01
  • 2017-03-12
  • 2013-04-25
  • 2021-12-09
  • 1970-01-01
  • 1970-01-01
  • 2013-02-22
  • 1970-01-01
  • 2014-01-30
相关资源
最近更新 更多