我不确定最好的方法:
我正在编写一个Web应用程序,它为许多" Project"实现了基本的CRUD功能。对象。因此,用户可以创建他/她自己的项目集。
我编写了一个用于添加/删除/列出项目的REST API,我编写了一个Reagent前端客户端。客户的项目保存在试剂原子(ratom)中,正如您所期望的那样。
这是有趣的地方。
在我看过的所有教程中,它向您展示了如何更新ratom,GUI将自动更新。我有,那有效。
我目前正在做的是,在更新客户端状态时,我进行REST POST调用以更新数据库上的服务器状态。
但是,这感觉不对。我现在将状态存储在两个地方:客户端和服务器上,两者可能不同。
如果我将其作为普通旧网页实现,服务器会将页面发送回客户端,其中包含数据库的最新状态。但是,状态已经存在于客户端中,并且我不知道应该如何同步它。
初始POST成功后,我是否应该再次调用服务器(GET请求)?这可以取代鼠标的内容。然后,我提出了两个请求......这似乎很浪费。
或者是使用和弦或 sente 等内容来异步管理客户端状态的最佳做法。这样会更好,因为这意味着来自其他用户的更改将在客户端即时刷新。但是,我无法看到任何教程证明与其中任何一个做出反应,所以也许我走错了路。
所以问题很简单,一个人应该如何与REST做出反应?
感谢
答案 0 :(得分:3)
我同意@myguidingstar您的问题更多是关于客户端 - 服务器同步而不是关于clojure或试剂。你可能会遇到类似的问题,比如GWT(去过那里......)
初始POST成功后,我是否应该再次调用服务器(GET请求)?这可以取代鼠标的内容。然后,我提出了两个请求......这似乎很浪费。
您似乎错过了POST请求也可以触发服务器的响应。
这里最大的问题是为什么你需要在客户端上使用DB状态?您是否有强制要求最小化从服务器获取数据的GET请求数量的要求?或者您是否在客户端(ClojureScript /试剂)方面实现了业务逻辑,而不需要服务器交互?您还需要考虑同一问题的另一面:如果您的客户状态暂时不更新或者您是否遇到一致性问题,这是否可以,因为"其他内容"正在修改客户端后面服务器上的数据?
最后,你说你
..不知道我应该如何同步它。
您的问题究竟是什么?为什么不在您从服务器提取数据后更新应用状态(swap! app-state update-in ...)
,如reagent-tutorial中所述?
答案 1 :(得分:1)
这是一个关于大多数网络应用都在努力解决的客户端 - 服务器同步问题。
Tonsky有一个关于这个问题的图书馆:
https://github.com/tonsky/datascript
阅读他的博文和示例datascript-chat
以了解设计。
这需要很多东西来学习,但我担心这是唯一没有“感觉不对”的方法。
答案 2 :(得分:1)
正如其他人所指出的,对于可能有多个客户端的任何客户端/服务器应用程序来说,这是一个常见的设计挑战。我认为关键在于密切关注您需要在客户端维护的状态。类似问题"您的客户端是否确实需要有关服务器或远程数据库的最新状态信息,或者它是否只需要有关客户端执行的操作的最新信息?例如,您是否需要在更新后知道远程数据库表中的内容,或者只是需要知道您的更新是否成功?
我所看到的另一件可能导致开发人员走错路的事情就是过早地追求效率。为了提高效率,设计有时会尝试在本地客户端中包含过多的状态,相信这会减少对远程服务器的调用次数并使应用程序更具响应性。但是,通常最终会出现一个过于复杂的实现,很难通过大量本地状态管理开销来实现,通常包括大量仅在客户端接口的有限或不经常使用的部分中使用/相关的信息。接下来你知道,你的应用程序正在失去效率,因为它可以维持不需要的状态同步。
这里的挑战是由于我们倾向于以连续的方式思考问题。这很自然。但是,这里的问题并不适合这种思维方式。系统的远程状态正以不可预测的速率变化。即使您采用的是将更改推送到客户端的体系结构,您也会遇到与计算推送此类更改的频率有关的问题,以及如何在界面中反映这些更改,以便用户stil获得一致性和有意义的画面
我的方法只是其中之一,可能不是最理想的方法,是将Web应用程序与许多数据库客户端(在某种程度上甚至是Clojure自己的STM)建模。客户端中的状态是特定时间点的远程状态的快照。它可能不准确或不是最新的,但它应该是一致的。当客户端提交更改时,它可能会也可能不会成功,具体取决于自从我开始在客户端中输入更改后服务器中的更改。如果成功,它会完全成功,如果失败,则完全失败。
正如其他人所指出的,这与Reagent没有直接关系。这是一个borader设计问题。但是,它可能会产生间接影响。例如,当您更新试剂原子时,将呈现包含er的试剂。原子知道什么时候更新,但它不知道什么时候更新只是刷新现有信息而没有变化,所以你真的只想更新原子,因为有些事情发生了变化。但是,除非真的经常发生这种情况并且您的组件非常复杂,否则即使您经常进行刷新类型更新,您也可能无法看到任何真正的影响。
我会专注于将状态保持在最低限度并开发一个非常简单的设计,然后加载测试并解决是否存在性能问题并在出现问题时进行处理。