瞬态 REST 表示
Posted
技术标签:
【中文标题】瞬态 REST 表示【英文标题】:Transient REST Representations 【发布时间】:2010-11-21 11:56:44 【问题描述】:假设我有一个 RESTful、超文本驱动的服务,它为冰淇淋店建模。为了帮助更好地管理我的商店,我希望能够显示每日报告,列出每种销售的冰淇淋的数量和美元价值。
似乎这种报告功能可以作为一种名为 DailyReport 的资源公开。 DailyReport 可以快速生成,并且在服务器上实际存储报告似乎没有任何优势。我只需要几天的 DailyReport,其他日子我不关心获得 DailyReport。此外,将 DailyReports 存储在服务器上会使客户端实现复杂化,需要记住删除不再需要的报告。
每日报告是短暂的;它的表示只能检索一次。实现这一点的一种方法是提供一个链接“/daily-reports”,一个 POST 将返回一个响应,其中包含一个 DailyReport 表示,列出了当天的销售信息。
编辑:假设我确实想做一个 POST 请求。 DailyReport 有许多不同的选项来创建视图,例如按字母顺序、按美元价值对冰淇淋类型进行排序 - 或包括每小时细分 - 或可选地包括当天的温度 - 或过滤掉某些冰淇淋类型(作为列表)。不是使用Get的查询参数,而不是使用适当的选项发布DailyReport表示(使用明确定义的自定义介质类型来记录每个选项)。我返回的表示将显示我的选项以及报告本身。
这是思考问题的正确方法,还是应该改用其他方法?如果正确,在实现 DailyReport 资源时,哪些特殊注意事项可能很重要? (例如,在 POST 请求后返回时设置 Location 标头可能不合适。
【问题讨论】:
【参考方案1】:如果您想提供过去几天的每日报告,您可以将其实现为 GET 到 /daily_reports/2009/08/20
。我同意 John Millikin 的观点,这里不需要 POST - 不需要像这样的东西成为用户可创建的资源。
将每天的报告作为其自己的 URI 提供的优点是可缓存性。
编辑: 一个好的解决方案可能是合并两个答案,使daily_report/
成为当天数据的无缓存表示,daily_reports/yyyy/mm/dd
成为全天数据的可缓存表示。
【讨论】:
最近做了类似的事情,除了我(到目前为止)将daily_report
非永久重定向到永久版本。【参考方案2】:
不需要为此使用 POST,因为请求报告不会更改服务器的状态。我会使用这样的资源:
GET /daily-report/
200 OK
Pragma: no-cache
<daily-report for="2009-04-20" generated-at="2009-4-20T12:13:14Z">
<!-- contents of the report here -->
</daily-report>
响应您的编辑:如果您将报告的描述发布到 URL,并因此检索临时数据集,那根本不是 REST。它是 RPC,与 SOAP 相同。 RPC 本身并不是一件坏事,但请不要称它为 RESTful。
【讨论】:
好点。如果有几个参数可以应用于 DailyReport - 例如按字母顺序或按美元数字排序冰淇淋类型 - 如果我不想使用查询参数来执行此操作怎么办?或者,如果我希望将日期范围设置为过去 24 小时以外的日期范围,即更通用的报告资源,该怎么办?假设我不想将这些选项作为查询参数包含在内,而是作为作为 POST 有效负载发送的完整表示?这更接近我的想法。 为什么不想使用查询参数?这就是他们存在的目的。也可以使用查询参数提供自定义报告范围。如果参数太复杂以至于无法在查询字符串中表示,那么可能值得将它们上传到服务器并将每日报告作为子资源。【参考方案3】:有时需要记录对报告的请求,在这种情况下,将 POST 发送到集合资源并非不合理。它对于您希望异步处理执行的长时间运行的报告也很有用。服务器将这些报告请求保留多长时间取决于您。
我会做类似的事情
POST /DailyReportRequests
这将返回请求的表示形式,包括选项,以及报告完成后,报告结果的链接。
当您拥有一组预置报告时,另一个很好的替代方法是创建一个包含预配置报告链接列表的 DailyReports 资源。 OpenSearchDescription 规范允许您使用 Query 标记执行类似的操作。
【讨论】:
【参考方案4】:我认为Greg's approach 是正确的。为了说明这一点,我认为您不应该提供每天更改的/daily-report
资源,因为在周二 11:59 运行报告会产生与周三在 00:01 运行报告不同的结果,这可能是 A)让期望资源相同的客户感到困惑,并且 B) 不允许客户在一天过去后检索前一天的数据。您应该为每个可用的每日报告提供一个唯一的资源标识符,以便客户可以随时访问他们需要的信息。
【讨论】:
拥有 /TodaysWeather 类型的资源是很常见的。当资源在 GET 之间发生变化时,客户端不应感到惊讶。 我同意 Darrel 的评论,只需添加正确的 expires 标头即可。获取代表当前检索到的内容的资源是完全有效的。如果您想让 API 使用者更清楚,您可能希望有单独的 URI 格式:/daily-report /archive/daily-reports/2009/02/12 我相信有人会跳进去提到 REST 没有关心 URI 设计,但它们对于设计可用的 API 很重要。以上是关于瞬态 REST 表示的主要内容,如果未能解决你的问题,请参考以下文章
在 Django REST Framework 中处理嵌套对象表示
Wordpress 说,“rest_upload_sideload_error”表示从 Google Apps 脚本上传的图像中的可识别类型。为啥?