短暂的REST表述

8
假设我有一个RESTful、超文本驱动的服务,模拟了一家冰淇淋店。为了更好地管理我的店铺,我想要能够显示每种冰淇淋销售数量和价值的日报表。
看起来这个报告功能可以作为 DailyReport 资源公开。DailyReport 可以快速生成,似乎没有任何实际存储报告在服务器上的优势。我只需要某些天的 DailyReport,其他天我不关心获取 DailyReport。此外,在服务器上存储 DailyReport 会使客户端实现复杂化,它们需要记住删除不再需要的报告。
DailyReport 是瞬时的;它的表示只能检索一次。一种实现方式是提供一个链接 "/daily-reports",对其进行POST将返回包含当天销售信息的 DailyReport 表示的响应。
编辑:还假设我真的想要进行 POST 请求。DailyReport 有许多不同的选项,例如按字母顺序排列冰淇淋类型、按价值排列、包括小时细分或可选择包括当天温度或过滤掉某些冰淇淋类型(作为列表)。与使用 GET 的查询参数不同,我宁愿使用带有适当选项的 DailyReport 表示进行 POST(使用定义良好的自定义媒体类型来记录每个选项)。我得到的表示将显示我的选项以及报告本身。
这是正确思考该问题的方法吗?如果正确,实现 DailyReport 资源时可能需要考虑哪些特殊因素?(例如,在进行 POST 请求后返回时设置 Location header 可能不合适)。
4个回答

4
如果你想要将过去的日报变得可用,可以将其实现为对 /daily_reports/2009/08/20 的GET请求。我同意John Millikin的观点,在这里不需要使用POST - 没有必要将这样的内容作为用户可创建的资源。
每天的报告都可以作为自己的URI进行访问,这样做的好处是可以进行缓存。
编辑:一个好的解决方案可能是将两个答案合并,使daily_report/成为当前日期数据的无缓存表示,而daily_reports/yyyy/mm/dd则成为完整一天数据的可缓存表示。

最近我做了类似的事情,不过到目前为止,我已经将“daily_report”设置为非永久重定向到永久版本。 - xenoterracide

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>

回应您的编辑:如果您正在将报告的描述POST到URL,并检索临时数据集作为结果,那么这根本不是REST。这是RPC,与SOAP类似。 RPC本身并不是坏事,但请不要称其为RESTful。

好的观点。如果有几个参数可以应用于DailyReport,例如按字母顺序或按美元数对冰淇淋类型进行排序,如果我不想使用查询参数怎么办?或者,如果我想将日期范围设置为其他时间而不是过去24小时,即更通用的报告资源怎么办?假设我不想将这些选项作为查询参数包含,而是作为POST负载发送的完整表示形式?那就更接近我所考虑的了。 - Rich Apodaca
为什么不想使用查询参数呢?这就是它们存在的原因。自定义报告范围也可以使用查询参数提供。如果参数太复杂,无法在查询字符串中表示,那么将它们上传到服务器并将每日报告作为子资源可能是值得的。 - John Millikin

2
有时候需要记录报告请求,这种情况下向集合资源进行POST是合理的。对于长时间运行的报告,您希望异步处理执行,这也很有用。服务器保留这些报告请求的时间长度由您决定。
我会做类似以下的操作:
POST /DailyReportRequests

该功能会返回请求的表示形式,包括选项,报告完成后会提供报告结果的链接。

另一个选择是在您有一组预定义报告时创建一个DailyReports资源,其中包含预配置的报告链接列表。使用OpenSearchDescription规范,可以使用查询标签执行类似的操作。


1

我认为Greg的方法是正确的。更进一步地说,我认为你不应该提供一个每天都会变化的/daily-report资源,因为在周二11:59运行报告将产生与在周三00:01运行它不同的结果,这可能会A)让客户感到困惑,因为他们期望资源是相同的,B)不允许客户在过去的日期之后检索前一天的数据。你应该为每个可用的每日报告提供唯一的资源标识符,这样客户可以随时访问他们需要的信息。


拥有类似于“今天天气”这样的资源是非常普遍的。当资源在GET请求之间发生变化时,客户端不应感到惊讶。 - Darrel Miller
我同意Darrel的评论,只需添加适当的过期标头即可。获取表示某个时间点当前状态的资源是完全有效的。如果您想让API使用者更清楚地了解,您可能需要有单独的URI格式:/每日报告 /存档/每日报告/2009/02/12我相信会有人跳出来说REST不关心URI设计,但是它们对于设计可用的API非常重要。 - Stephen Petschulat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接