休息 API 和 UUID
Rest API and UUID
使用 UUID 的原因之一,也可能是主要原因,是为了避免让 "centralized" 点负责为资源创建和分配 ID。
这意味着,对于 REST APIs,客户端可以(并且应该)能够生成,并在他们 POST 特定资源时为特定资源提供 UUID第一次。这将最大程度地减少与首次成功 post 获取资源但未返回 ID 作为响应相关的问题(例如连接问题)。这可能会导致某些客户端出现新的 post,从而生成重复的资源。
我的问题是:
- 让客户端生成 UUID 并在 REST 中公开 API 是最佳实践吗?
- 还有其他替代方案吗?
REST 并不关心 UUID 是由服务器还是客户端生成的。它只需要 URI 形式的唯一 resource-identifier。
URI 的形式对客户端和服务器来说并不重要 - 只有它们是唯一的并且可以由客户端获得(HATEOAS)。当然,您还需要服务器端的资源,它能够为您创建 sub-resource 并了解您想要提供 UUID 而不是生成自己的 UUID。你可以 f.e 而不是 UUID。还可以使用 blog-post 的 url-encoded 标题或类似此问题的 hash-value 和 question-title 31584303/rest-api-and-uuid
的组合来唯一标识资源。
在我看来,由客户端生成 UUID 在实践中并不常用,但我在这件事上可能是错误的。实际的问题是,为什么客户端真的应该提供自己的 UUID 而不是让服务器创建一个?客户端是,IMO,只对将数据发送到服务器感兴趣,并有某种方式在以后的某个时间检索它,这将通过 POST 的响应中返回的位置 header 提供要求。
如果连接问题是一个实际问题,您可以让客户端发送一个空 POST 来创建资源并发回 header 中的位置。然后通过 PUT 请求添加内容。
仍然可能涉及一些连接问题:
- 请求没有到达服务器
- 响应未到达客户端
虽然第一个对于客户端和服务器都没有问题,因为不执行任何操作并且可以简单地重新发送请求,但后者实际上会在服务器端创建资源,尽管 link 永远不会到达客户端。因此,除非您提供一种遍历所有资源的方法,否则实际资源处于不可引用状态,其中还包含空资源。
服务器可以在后面有一个清理线程,它在给定的时间后删除空资源。如果客户端再发送一个空 POST 请求,但这次也收到创建资源的 URI,他可以通过 PUT
更新资源的状态。 PUT 是幂等的。如果服务器没有收到请求,客户端可以简单地重新发送它。 PUT 具有更新现有资源或创建新资源(如果尚不可用)的语义。因此,服务器可以在这种情况下使用提供的内容创建资源。如果请求确实到达了服务器,则进一步的更新不会更改资源的状态。
客户端生成的 UUID 的一个优点是:客户端甚至在创建资源之前就知道资源密钥。无需阅读 POST/PUT 的响应,错误除外
使用 UUID 的原因之一,也可能是主要原因,是为了避免让 "centralized" 点负责为资源创建和分配 ID。
这意味着,对于 REST APIs,客户端可以(并且应该)能够生成,并在他们 POST 特定资源时为特定资源提供 UUID第一次。这将最大程度地减少与首次成功 post 获取资源但未返回 ID 作为响应相关的问题(例如连接问题)。这可能会导致某些客户端出现新的 post,从而生成重复的资源。
我的问题是:
- 让客户端生成 UUID 并在 REST 中公开 API 是最佳实践吗?
- 还有其他替代方案吗?
REST 并不关心 UUID 是由服务器还是客户端生成的。它只需要 URI 形式的唯一 resource-identifier。
URI 的形式对客户端和服务器来说并不重要 - 只有它们是唯一的并且可以由客户端获得(HATEOAS)。当然,您还需要服务器端的资源,它能够为您创建 sub-resource 并了解您想要提供 UUID 而不是生成自己的 UUID。你可以 f.e 而不是 UUID。还可以使用 blog-post 的 url-encoded 标题或类似此问题的 hash-value 和 question-title 31584303/rest-api-and-uuid
的组合来唯一标识资源。
在我看来,由客户端生成 UUID 在实践中并不常用,但我在这件事上可能是错误的。实际的问题是,为什么客户端真的应该提供自己的 UUID 而不是让服务器创建一个?客户端是,IMO,只对将数据发送到服务器感兴趣,并有某种方式在以后的某个时间检索它,这将通过 POST 的响应中返回的位置 header 提供要求。
如果连接问题是一个实际问题,您可以让客户端发送一个空 POST 来创建资源并发回 header 中的位置。然后通过 PUT 请求添加内容。
仍然可能涉及一些连接问题:
- 请求没有到达服务器
- 响应未到达客户端
虽然第一个对于客户端和服务器都没有问题,因为不执行任何操作并且可以简单地重新发送请求,但后者实际上会在服务器端创建资源,尽管 link 永远不会到达客户端。因此,除非您提供一种遍历所有资源的方法,否则实际资源处于不可引用状态,其中还包含空资源。
服务器可以在后面有一个清理线程,它在给定的时间后删除空资源。如果客户端再发送一个空 POST 请求,但这次也收到创建资源的 URI,他可以通过 PUT
更新资源的状态。 PUT 是幂等的。如果服务器没有收到请求,客户端可以简单地重新发送它。 PUT 具有更新现有资源或创建新资源(如果尚不可用)的语义。因此,服务器可以在这种情况下使用提供的内容创建资源。如果请求确实到达了服务器,则进一步的更新不会更改资源的状态。
客户端生成的 UUID 的一个优点是:客户端甚至在创建资源之前就知道资源密钥。无需阅读 POST/PUT 的响应,错误除外