为什么我不相信客户端生成的GUID?将PK视为客户端GUID和服务器GUID的组合可以解决任何问题吗?

Sea*_*son 8 guid client-server client-side primary-key composite-key

我正在与Jon Skeet先前的讨论建立起来.

我的方案的要点如下:

  • 客户端应用程序能够创建需要持久保存在数据库中的新"PlaylistItem"对象.
  • 用例需要以这样的方式创建PlaylistItem:客户端在显示PlaylistItem之前不必等待来自服务器的响应.
  • 客户端为PlaylistItem生成UUID,在客户端中显示PlaylistItem,然后向服务器发出save命令.

此时,我理解使用客户端生成的UUID作为数据库中对象的PK是不好的做法.原因是恶意用户可以修改生成的UUID并强制我的数据库上的PK冲突.

为了减轻因在PlaylistItem上强制PK冲突而导致的任何损害,我选择将PK定义为两个ID的组合 - 客户端生成的UUID和服务器生成的GUID.服务器生成的GUID是PlaylistItem的播放列表ID.

现在,我一直在使用这个解决方案,但我不明白为什么/相信我的解决方案比简单地信任客户端ID更好.如果用户能够强制PK collison与另一个用户的PlaylistItem对象,那么我认为我应该假设他们也可以提供该用户的PlaylistId.他们仍然可以强制使用collisons.

是的.做这样的事情的正确方法是什么?允许客户端创建UUID,服务器在成功保存后会竖起大拇指.如果发现冲突,请恢复客户端更改并通知检测到的collison?

zaf*_*s.m 3

一个不错的解决方案如下:引用 Sam Newman 的“构建微服务”

调用系统将发布一个 BatchRequest,可能会传入一个可以放置包含所有数据的文件的位置。客户服务将返回 HTTP 202 响应代码,表明请求已接受,但尚未处理。然后,调用系统可以轮询等待的资源,直到检索到 201 Created 指示请求已得到满足

因此,在您的情况下,您可以 POST 到服务器,但立即得到类似“我将保存 PlaylistItem 并且我保证其 Id 将是这个”的响应。然后,客户端(和用户)可以继续,而服务器(甚至可能不是 API,而是一些从 API 获取消息的后台处理器)需要时间来处理、验证和执行其他可能繁重的逻辑,直到保存实体。如前所述,API 可以为该请求的状态提供 GET 端点,客户端可以轮询它并在出现错误时采取相应的操作。