ReST 低延迟 - 在上传待处理时我应该如何回复 GET?

2024-01-09

我正在设计一个ReST https://restfulapi.net/遵循基本的APICRUD https://en.wikipedia.org/wiki/Create,_read,_update_and_delete图案。

我的 API 可以接收更新资源的请求,该请求可能需要很短的时间来处理。理想情况下,我想通知客户新版本即将推出,并且我缓存的版本何时实际过期存在一些不确定性。

所以我打算使用这样的过程(欢迎​​改进):

client: GET /some/item
myapi:  200 OK
        last-modified: time-stamp-of-v1
        etag: some-hash-relating-to-v1-of-my-item-in-this-format
        content: json or whatever
         data/for/some/item/v1... 

client: PUT /some/item
        if-match: some-hash-relating-to-v1-of-my-item-in-this-format
        content: json or whatever
         data/for/some/item/v2... 

myapi:  202 ACCEPTED,   
        content: json or whatever
         time-accepted: time-stamp-after-v1-but-before-v2
         your item will be at /some/item
         here is a URI /some/taskid to track progress

当上传等待时:

client: GET /some/item
myapi:  200 OK
        some/item ... 
        last-modified: time-stamp-of-v1
        etag: some-hash-relating-to-v1-of-my-item-in-this-format
>>>>    expires: time-stamp-after-v1-but-before-v2 <<<
>>>>    warning: 110 Response is stale    <<<<
        content: json or whatever
         data/for/some/item/v1... 

client: GET /some/task/id
myapi:  200 OK
        content: json or whatever
         time-accepted: time-stamp-after-v1-but-before-v2
         your item will be at /some/item
         status/of/upload/v2... 

任务完成后:

client: GET /some/item
myapi:  200 OKAY
        some/item/v2 ... 
        last-modified: time-stamp-of-v2
        etag: some-hash-relating-to-v2-of-my-item-in-this-format
        content: json or whatever
         data/for/some/item/v2... 

client: GET /some/task/id
myapi:  303 SEE OTHER
         look-here: /some/item

如果您是代理并且知道您的内容已过时,您可以在标头中添加“警告:110 - 响应已过时”。 然而,在这种情况下,数据实际上还不是无效的。 我想说的是,我可以保证它在我收到并传递上传请求之前一直有效(v1 之后但 v2 之前的时间戳或稍后,就像我与上传服务器联系一样)。当我收到上传请求时,它还没有真正过期。我只是期待它会发生。 (事实上​​,如果请求失败,它可能根本不会更新)。

现在,默认选择只是提供旧内容并让客户端自行赶上。这具有高延迟。如果可以的话,我想做得更好。

例如,如果客户端知道文档即将过期,它可以更频繁地轮询,或者可以尝试升级到 Web 套接字的连接,并在我收到它时立即发送更新(这仍然算作 ReST 吗?)

还有另一种情况,必须不惜一切代价避免使用过期数据。对于这种情况,我想我想告诉客户端资源暂时不可用。像我上面那样使用警告和过期字段似乎是正确的。不过,发送带有合适的重试后标头的 503 可能会更好。

所以问题是:当新版本上传待处理时,我应该如何回复 GET?

考虑到使用 AMQP 或 ZeroMQ 等消息传递框架来实现低延迟的答案,我应该指出,此 API 充当不愿意直接使用 AMQP 的客户端的 AMQP 网关/代理。有关使用 webhook 或 websocket 的信息仍然很有趣。

一些相关的有用内容是:

  • 如何正确设计一个 Restful API 来使缓存失效? https://stackoverflow.com/questions/13291805/how-to-proper-design-a-restful-api-to-invalidate-a-cache
  • https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
  • 暂时不可用页面的 HTTP 状态代码 https://stackoverflow.com/questions/4642923/http-status-code-for-temporarily-unavailable-pages
  • http://www.albertoleal.me/posts/how-to-prevent-race-conditions-in-restful-apis.html http://www.albertoleal.me/posts/how-to-prevent-race-conditions-in-restful-apis.html(etag 阻止比赛同时上传)

Tl;Dr;

当上传等待时发送:

client: GET /some/item
myapi:  200 OK
        some/item ... 
        last-modified: time-stamp-of-v1
        etag: some-hash-relating-to-v1-of-my-item-in-this-format
        expires: time-stamp-after-v1-but-before-v2
        stale-while-revalidate: 100
        warning: 110 Response is stale
        content: json or whatever
         data/for/some/item/v1... 

乍一看,它看起来像使用Warning是不正确的。看https://www.rfc-editor.org/rfc/rfc7234#section-5.5.0 https://www.rfc-editor.org/rfc/rfc7234#section-5.5.0

在这种情况下,服务器充当代理(尽管不是 HTTP 代理)。 它不会与 AMQP 断开连接,并且除非断开连接,否则“代理不得发送过时的响应”。 这很烦人,因为这看起来是正确的做法。

4.2.4.提供过时的响应

“过时”响应是指明确过期的响应 信息或允许计算启发式到期时间,但是 根据 4.2 节的计算,这并不新鲜。

如果缓存被禁止,则不得生成陈旧响应 明确的协议内指令(例如,通过“no-store”或 “no-cache”缓存指令,“必须重新验证” 缓存响应指令,或适用的“s-maxage”或 “代理重新验证”缓存响应指令;参见第 5.2.2 节)。

**> 缓存不得发送过时的响应,除非它已断开连接

(即,它无法联系原始服务器或以其他方式找到
前向路径)或这样做是明确允许的(例如,由
max-stale 请求指令;参见第 5.2.1 节)。**

缓存应该生成一个带有 110 的警告头字段 过时响应中的警告代码(请参阅第 5.5.1 节)。同样,一个 缓存应该在过时生成 112 警告代码(参见第 5.5.3 节) 缓存断开连接时的响应。

当以下情况时,缓存不应生成新的警告标头字段:
转发没有 Age 标头字段的响应,即使 响应已经过时了。缓存不需要验证响应
只是在运输过程中变得陈旧。

Also

4.4.无效

因为不安全的请求方法([RFC7231]的第4.2.1节)例如 PUT、POST 或 DELETE 有可能改变状态
原始服务器,干预缓存可以使用它们来保存其内容 最新。

**> 缓存必须使有效的请求 URI 无效(第 5.5 节)

[RFC7230])以及位置和内容位置中的 URI 当非错误状态代码为时的响应标头字段(如果存在)
收到的响应不安全的请求方法。**

但是,如果出现以下情况,则需要发出警告:重新验证时过时被使用(参见https://www.rfc-editor.org/rfc/rfc5861 https://www.rfc-editor.org/rfc/rfc5861)

  1. 重新验证时失效的缓存控制扩展

当出现在 HTTP 响应中时,stale-while-revalidate Cache- 控制扩展指示缓存可以在以下位置提供响应
它在变得陈旧后出现,最多达到指定的数量
秒。

 stale-while-revalidate = "stale-while-revalidate" "=" delta-seconds

如果由于存在此问题而导致缓存的响应过时
扩展,缓存应该尝试重新验证它,同时仍然
提供过时的响应(即不阻塞)。

我认为这不清楚,所以我提交了一份errata https://www.rfc-editor.org/errata/eid5564。这被拒绝了(尽管在撰写本文时仍显示为报告的内容),因为 rfc5861 中的缓存控制扩展覆盖了 rfc7234 中的“不得”(“明确允许这样做”,请参见上文)。

使用就可以了expires但它不是很有帮助,因为它没有暗示任何东西。

5.3.过期

“Expires”头字段给出了日期/时间,在此之后
响应被认为是陈旧的。进一步讨论请参见第 4.2 节 的新鲜度模型。

**> Expires 字段的存在并不意味着原始的

资源将在该时间、之前或之后发生变化或不再存在
time.**

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ReST 低延迟 - 在上传待处理时我应该如何回复 GET? 的相关文章

随机推荐

  • Python - LightGBM 与 GridSearchCV,永远运行

    最近 我正在做多个实验来比较Python XgBoost和LightGBM 看来这个LightGBM是一种新算法 人们说它在速度和准确性上都比XGBoost更好 This is LightGBM GitHub https github co
  • 自动将根路径重定向到 Spring Boot 上下文路径

    我正在使用 application properties 文件中指定的 Spring Boot 上下文路径 并且效果很好 server port 5000 server context path services Spring Boot 2
  • 改变元素之间文本选择的顺序

    说我有这个 div position absolute top 0 right left 50px left left 0 div World div div Hello div 当我从左到右选择文本时 它的行为在视觉上不直观 至少在 Ch
  • 设计长期运行、资源密集型 Web 服务的建议

    我有一个 NET 函数可以执行一些复杂的计算 根据传入的参数 该函数 运行时间从几分钟到几个小时不等 计算期间使用 100 单核 需要 100 MB 到几 GB 内存 将几 MB 到几 GB 的数据写入磁盘 可能会抛出异常 包括 OutOf
  • 使用 Flask 从下拉菜单中获取数据

    我对 Flask 完全陌生 并且真的完全不知道如何解决这个问题 我已经研究过其他问题 但无论如何我似乎都无法使其正常工作 我有这样的表格
  • Ionic:导航到另一个视图时保留 $scope

    我正在使用 Ionic Framework Angular Cordova 开发一个应用程序 该应用程序有一个新闻部分 其中包含从 JSON 格式的服务器加载的新闻列表 然后我点击一个新的以打开单个新闻的视图 但是当返回到新闻列表时 sco
  • Flutter中是否可以使用JS可视化库(例如Chart.js或D3.js)?

    如果可能的话 它到底是如何运作的 也许可以访问 Flutter 的Canvas https api flutter dev flutter dart ui Canvas class html通过JS小部件 我对此最好的猜测是flutter
  • JNI 环境指针

    我有一个 Java 类 其中有一个必须从 C 代码调用的函数 函数如下 public void endTrial Code 所以我在我的 C 文件中创建了以下代码 JNIEXPORT void JNICALL package endTria
  • 获取 post_save 信号中字段的先前值

    我在 django 中有一个 post 信号 我需要访问字段的先前值 post save connect callback function postsave sender Media 我知道理想情况下我应该使用 pre save pre
  • UITableView reloadData() 不刷新显示的单元格

    I have class StationViewController UITableViewController UITableViewDelegate UITableViewDataSource IBOutlet var stationT
  • 包括所有依赖项

    我刚刚开始使用 WiX 因为我需要能够在我们的 CI 服务器上自动构建 MSI 有没有办法自动包含项目的所有依赖项 heat exe 的 proj 扩展变得越来越好 Heat http wixtoolset org documentatio
  • 对命名实体使用(NLP)门工具[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我可以使用GATE吗http gate ac uk http gate ac uk 在我的java程序中提取命名实体 如果是 您能否举
  • sphinx-build 失败 - autodoc 无法导入/查找模块

    我正在尝试开始使用 Sphinx 但似乎遇到了无情的问题 命令 docs sphinx quickstart 我回答了所有问题 一切正常 命令 docs ls 一切看起来都很正常 结果 build Makefile source 命令 sp
  • 改变网格的不透明度会产生“淡入”效果吗?

    我在创建网格淡入淡出效果时遇到一些问题 我想要点击后出现一个网格 这可能吗 Thanks 参加派对有点晚了 因为我刚刚写的与隐士戴夫几乎相同 但也许它有助于更 好地理解 另一种方法是 在 XAML 视图中设置 Storyboard 项 在我
  • 正则表达式不允许使用字符,除非转义

    下面是我的正则表达式来解析逗号分隔的键值对 function extractParams str var result str replace s s s s g function a b result a trim b trim retu
  • 如何在 Ruby 中创建双向 SSL 套接字

    我正在构建一个客户端 Ruby 库 它连接到服务器并等待数据 但也允许用户通过调用方法发送数据 我使用的机制是有一个初始化套接字对的类 如下所示 def initialize pipe r pipe w Socket pair UNIX S
  • 无法删除目录 ACE

    我正在使用 C 和 NET 4 编写一个类库 它通过网络与共享服务器上的文件系统进行交互 我正在尝试调整文件夹的某些权限 并且我完全有能力添加 ACE 但我很难删除它们 这是我到目前为止的代码 get ACEs for the workin
  • JPA 多线程 org.eclipse.persistence.exceptions.ConcurrencyException

    嗨 我尝试使用多线程JSOUP and JPA解析一些页面并将信息放入数据库中 但有时我会遇到此异常 Exception in thread Thread 7 Local Exception Stack Exception EclipseL
  • 多线程和递归结合在一起

    我有递归代码以深度优先的方式处理树结构 代码基本上是这样的 function TreeNode curr if curr children null curr children isEmpty for TreeNode n curr chi
  • ReST 低延迟 - 在上传待处理时我应该如何回复 GET?

    我正在设计一个ReST https restfulapi net 遵循基本的APICRUD https en wikipedia org wiki Create read update and delete图案 我的 API 可以接收更新资