如何/应该在对其执行非幂等HTTP请求之前缓存资源?

时间:2015-06-29 12:52:07

标签: android rest caching realm

我的客户端应用程序(在这种情况下为Android)需要POST到集合。虽然我可以简单地POST,然后保存/缓存返回的资源,但我希望在它到达服务器之前保存我的资源版本。

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

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

如何正确持久并更新" partial / POSTing"资源,因为它还没有有效的主键?

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

[primaryKey(基于服务器)|电子邮件| ...... | RestMethod(GET / POST / etc)| lastRequestFinished]

  1. 存储部分创建: [ someNumber | " me@email.com" | ...... | POST |假]

  2. 发出 POST (应用可能会在这里中断)

  3. 处理 POST 响应,更新早期的部分资源
  4. [1091809 | " me@email.com" | ...... | POST |是的]

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

3 个答案:

答案 0 :(得分:0)

试试这个:

// 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();

答案 1 :(得分:0)

你想要实现的目标在我看来有点矫枉过正。如果您要发布的资源没有唯一的属性,如用户名或电子邮件地址或类似的东西,这可能很重要,而且情况并非如此(它是是这种情况找到一种方法来为资源生成一个唯一的ID。)因为你使用 REALM 来持久我鼓励你在id和领域使用@primaryKey将确保没有两个Model将拥有相同的字段。

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

如果您不是控制其余API的人,那么每当有人尝试创建已存在的资源(例如用户名)时,请与负责人通信以返回特定的响应代码注册的是另一个用户作为新用户再次发送的。然后由你来检查响应代码说 400 BAD REQUEST 然后,你的工作是处理错误,也许你会通知用户电子邮件或用户名已经存在。有帮助的跳跃。

答案 2 :(得分:0)

我忽略了提到我也控制了API。我找到的最优雅的解决方案是通过利用公开给客户端的新UUID字段将所有集合 POST 转换为实例 PUT

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

class OldUser(DbModel):
    id = PrimaryKeyField()

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

在User示例中,android应用程序现在发出带有生成的client_id的PUT。如果我PUT /users/<client_id>,我可以放心,无论我做出多少PUT请求,它都只会影响单个实例。用于确定我是否具有该资源的最新缓存的业务逻辑变得极大简化。在原始问题的最终建议之外,我没有看到在不改变API的情况下在非安全HTTP方法上完成预请求缓存的另一种方法。