基于If-Modified-Since标头修改REST API表示是否有效?

foo*_*sus 8 rest if-modified-since

我想在我的API中实现"获取更改值"功能.例如,假设我有以下REST API调用:

GET /ws/school/7/student
Run Code Online (Sandbox Code Playgroud)

这让所有学生都在学校#7.不幸的是,这可能很多.因此,我想修改API以仅返回自特定时间以来已修改的学生记录.(用例是夜间进程从另一个系统运行,将所有学生从我的系统中拉到他们的系统.)

我看到http://blog.mugunthkumar.com/articles/restful-api-server-doing-it-the-right-way-part-2/建议使用if-modified-since标头并返回如下表示:

  • 搜索自if-modified-since标头中请求的时间以来更新的所有学生
  • 如果有,请返回那些200 OK的学生
  • 如果没有从该查询返回的学生,则返回304 Not Modified

我理解他想做什么,但这似乎是错误的方法.If-Modified-Since标题的定义(http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.24)说:

If-Modified-Since请求标头字段与方法一起使用以使其成为条件:如果请求的变体自该字段中指定的时间以来未被修改,则不会从服务器返回实体; 相反,将返回304(未修改)响应,而不返回任何消息体.

这对我来说似乎不对.我们不会返回RFC所示的表示或304,而是一些混合.看起来客户端代码(或者更糟糕的是,服务器和客户端之间的Web缓存)可能会错误地解释其含义并替换本地缓存值,而它应该只是更新它.

那么,有两个问题:

  • 这是正确使用标题吗?
  • 如果不是(我怀疑不是),最佳做法是什么?查询字符串参数?

Tim*_*lds 7

这不是标头的正确使用.If-Modified-Since标头是HTTP客户端(浏览器或代码)在请求资源时可选择提供给服务器的标头.如果提供的意思是"我想要资源X,但只有当它从时间T开始改变时".其目的是允许客户端缓存资源.

您提议的用法的语义是"我希望从时间T开始发生对集合X的更新".这是对X子集的请求.似乎您的动机不是启用缓存.您的客户端缓存表示似乎包含所有X,即使典型请求只会返回一小组X更改; 也就是说,响应不是你直接缓存的,所以缓存需要在自定义用户逻辑客户端进行.

查询字符串参数是一个更合适的解决方案.下面{seq}将是序列号或时间戳.

GET /ws/schools/7/students/updates?since={seq}
Run Code Online (Sandbox Code Playgroud)

服务器端我想你自系统开始以来就有一系列更新,并且上述表单的请求将获取序列值大于的前N个更新{seq}.通过这种方式,如果客户远远落后并且需要赶上,那么结果将被分页.