How/Should 我在执行非幂等 HTTP 请求之前缓存资源?

How/Should I cache a resource before performing a non-idempotent HTTP request on it?

我的客户端应用程序(在本例中为 Android)需要 POST 到一个集合。虽然我可以简单地 POST 然后 save/cache 返回资源,但我想在它到达服务器之前保存我的资源版本。

为什么要尝试这个?如果应用程序意外中断,我希望资源标记为 "POSTing",因为 HTTP 201 响应处理程序被中断。通过这种方式,应用程序可以合并逻辑来检查我的 POST 在非正常退出之前是否成功,以避免重复的 POSTs.

我不确定这种做法是否完全被建议或标准,但话虽如此,我的下一个问题是如何实现 POST 之前的资源节省。我的客户端缓存(目前使用 Realm for Android)有一个基于服务器主键的主键。我保存了在资源上发布的最后一个 REST 方法的名称和一个布尔值是否已完成。

由于 "partial/POSTing" 资源还没有有效的主键,我该如何正确地保存和更新它?

例如,考虑一个具有架构的新用户:

[ primaryKey(基于服务器)|电邮 | ... |休息方法(GET/POST/etc) | lastRequestFinished ]

  1. 存储部分创建: [ 一些数字 | "me@email.com" | ... | POST |假]

  2. 发出POST(此处可能会中断app)

  3. 处理POST响应,更新之前的部分资源

[ 1091809 | "me@email.com" | ... | POST |真]

更新主键字段当然不标准,会导致棘手的错误,并引入非直观的逻辑。有没有更好的办法?也许,我应该有一个客户端主 ID 和一个服务器端主 ID?

试试这个:

// This will create a RealmObject without proxy which means the setters
// won't write data to Realm when you call them.
User user = new User();
user.setEmail("xxx");

// Next loop you get the primary key
...
user.setPrimaryKey(key);
// Then we can write it to Realm
realm.beginTransaction();
// Return value will be the RealmObject with proxy which means setters
// will write data to Realm without calling copyToRealmOrUpdate.
user = realm.copyToRealmOrUpdate(user);
realm.commitTransaction();

在我看来,您尝试实现的目标 overkill.It 可能很重要,如果您尝试 post 的资源没有唯一 属性 用户名或电子邮件地址或其他内容那种情况,这几乎不是这种情况(这种情况找到了一种为资源生成唯一ID的方法)。当你使用 REALM 进行持久化时,我鼓励你使用id 和 realm 上的 @primaryKey 将确保没有两个 Model 具有相同的字段。

我强烈建议您等到从后端获得成功响应后再保留资源。仍在使用领域只需调用 Model resource = new Model() 并且在您调用 Realm#copyToRealm(RealmObject) 或其变体之前它不会被保留。

如果您不是控制其余部分的人 API,则与负责人联系 return 每当有人尝试创建一个特定的响应代码时已经存在的资源,比如注册的用户名正在作为新用户再次发送给另一个用户。然后由您检查响应代码说 400 BAD REQUEST 然后,处理错误是您的工作,也许您会通知用户电子邮件或用户名已经存在。跳有帮助。

我忘了说我也控制着 API。我找到的最优雅的解决方案是通过利用向客户端公开的新 UUID 字段将所有集合 POSTs 转换为实例 PUTs

API 现在有一个私有主键字段,但公开了一个 client_id UUID 字段。像这样:

class OldUser(DbModel):
    id = PrimaryKeyField()

class NewUser(DbModel):
    id = PrimaryKeyField()
    client_id = UUIDField(default=uuid4, unique=True)

在用户示例中,android 应用程序现在使用生成的 client_id 发出 PUT。如果我PUT /users/<client_id>,我可以放心,无论我发出多少PUT请求,它只会影响单个实例。确定我是否拥有该资源的最新缓存的业务逻辑变得非常简单。除了我在原始问题中的最终建议之外,我没有看到另一种在不改变 API.

的情况下在非安全 HTTP 方法上完成预请求缓存的方法