文件转换服务的有效 REST 方法是什么?

What would be a valid REST approach for a file conversion service?

允许客户端调用 RESTful 服务以将(大型)文档转换为目标格式的适当 REST 兼容方法是什么?

我在想类似的事情:

  1. 客户端在 /conversion/request 资源上使用转换配置(目标类型、安全密钥、通知资源 URL 形式 http://host_to_be_notified/notification/status/id)创建一个 POST,这将 return 请求 ID。转换请求将被添加到一个内部队列中,只要转换没有开始,客户端就可以修改/删除。
  2. 转换开始后,服务器会删除 /conversion/request/id
  3. 转换完成后,服务器会创建一个 /conversion/result/id(与上面 1 中的 ID 相同)资源,然后在通知状态资源上执行 PUT(将其设置为 "ready" 并提供密钥) 将通知客户端其请求已完成
  4. 准备好后,客户端在 /conversion/result/id 资源上创建 GET 以获取转换后的文档
  5. 如果客户端因为任何原因掉线了,他可以像4那样尝试检索结果。如果文档没有准备好,客户端只需要等待通知发送即可。

然而...

  1. 这是一种有效的方法吗?
  2. 我是否应该忘记使用 REST 而应该考虑使用 SOAP(并且有一个阻塞调用,知道我更愿意避免阻塞调用)或 JMS(所有方法都有它们的 pros/cons,并且一个在我的上下文中,针对 JMS 的一大缺点是它需要为所有可能被拒绝的客户端设置队列)(注意:这就是为什么我还在这个问题中添加了 "SOAP" 和 "JMS" 标签)
  3. 知道如何改进该方法吗?在继续之前我应该​​考虑哪些问题?

在此先感谢您的帮助!

米歇尔

过去,我用 POST 作为初始请求来处理这个问题,return 将 URI 与最终文档的位置作为有效负载。然后我在该位置用 HTTP 202 响应响应 GETS,直到处理完成。处理完成后,我 return HTTP 200,以及内容。这最大限度地降低了客户端的复杂性(这是一个简单的轮询),并且与 HTTP 语义保持一致。

如果你真的想实现一个回调方法,你可以,但它增加了显着的复杂性,我无法想象它会简化另一端的事情。轮询过程使他们可以更自由地实施 try/wait-loop 或将位置转储到 table/queue 以进行批处理。

最后,此方法显着简化了错误处理。您总是可以 return 在客户端正在执行的同一个 GET 上出现 500 错误。您不必为不同的错误条件指定不同的回调(这最终成为您 API 的真正痛点)。

我会像这样只使用一个资源:

POST /conversion/ {meta} {attachment} -> 201 created {links: [{rel: "self", href: "/conversion/1"}]}

之后,转换表示将包含属性和处于不同状态的链接:

排队

{
    id: 1,
    status: "enqueued",
    links: [
        {rel: "self", href: "/conversion/1"},
        {rel: "remove", href: "/conversion/1"},
        {rel: "status-change", href: "/conversion/1/status/events"}
    ]
}

处理中

{
    id: 1,
    status: "processing",
    percent: 99,
    links: [
        {rel: "self", href: "/conversion/1"},
        {rel: "status-change", href: "/conversion/1/status/events"},
        {rel: "percent-change", href: "/conversion/1/percent/events"}
    ]
}

完成

{
    id: 1,
    status: "complete",
    links: [
        {rel: "self", href: "/conversion/1"},
        {rel: "result", href: "/conversion/1/file"}
    ]
}

status-changepercent-change 可以使用 SSE、轮询或 websockets 来推回数据或触发更新。 Ofc。这只是草稿。