我刚刚开始尝试理解REST设计原理,并且正在努力解决我正在尝试的第一个例子。
让我们说我想要做的是设计一个类似SSH会话的REST API。忽略安全性,登录等,我假设的是会有类似/ sessions URI的东西,我通过POST到/ sessions指定连接信息,主机名,用户名等事情来启动SSH会话。这将导致服务REST API的Web服务器代表我发起SSH会话,为其分配某种ID并返回URI / sessions / [id]。然后,我可以使用该URI的子资源与该会话进行交互。这不是我想要做的非常好的类比,但它有一个关键点,即尝试定义具有“会话”的东西的接口,并且当我将事物发送到资源时其状态发生变化在其中。
现在我的问题是它的可扩展性,但我想不出更好的东西。它依赖于Web服务器启动与主机的SSH连接,并且该连接必须由Web服务器维护(因此如果必须回收Web服务器,则会丢失)。它还将我的请求与单个Web服务器联系在一起 - 我不能轻易地拥有处理API请求的Web服务器场。
我可以将SSH连接的创建和维护移动到某个地方的另一台服务器,但这只会真正影响可伸缩性问题。无论如何,那么我需要为该服务器定义一个API,为什么我不把它变成一个REST API,在这种情况下,我只是复制了第一个,无限制。
现在我可能只是以错误的方式看待这个问题,而不是以资源为中心,但在我看来,“资源”就是SSH连接。我的问题是资源不是容易共享的东西 - 它是Web服务器创建的东西,本质上是瞬态的。
是否有任何RESTful API设计专家愿意帮助我走上更好的道路? 请注意,我实际上并不认为这确实是特定于REST的 - 我会想到我将基于Web服务交互帐户设置为无状态时所采用的方法。 / p>
感谢。
[编辑:]这种方法的另一个问题是当客户端没有明确删除它们时“泄漏”“会话”资源。我能想到的最明智的解决方案是定义会话的某些属性(可能在创建时可设置,可能是固定的),它定义了在被认为是陈旧和删除之前需要再次联系会话的时间。客户端将访问此属性(比如/ sessions [id] / keepalive或其他东西),它将返回一个时间戳,将其除以2(从现在开始到之后的一半时间点)并确保如果没有别的话“轮询”服务器通过在此之前再次访问相同的资源。如果失败,那么会话将被回收。 这是我能想到的最“RESTful”的方法,但是会重视经验丰富的RESTful思想。
答案 0 :(得分:2)
通常为了能够将某些东西声明为资源,它需要存储在某种持久存储中,或者它应该易于重现。 正如你所说,尝试和建模资源会话是一个非常短暂的事情。它也通常与单个客户端相关联。但是,资源通常是共享的,这是分配公共URI的一个原因。所有这些都说你试图在一个方孔中安装一个圆钉。
话虽如此,如果你真的想要这样做,并且你想要向外扩展,那么我可以想到两种可能的方式。一种是在单个“DB”服务器上启动会话。这将允许您扩展Web服务器。根据大部分工作的完成情况,这可能有也可能没有任何价值。
另一种选择是利用超媒体来允许您使用Web服务器作为会话启动器,但您需要确保Web服务器主机名是会话资源URI的一部分。 REST客户端不应该对URI做任何假设,并且应该始终从之前的响应中读取它们。如果您使用此优势,您可以在各种Web服务器上分发会话,客户端只需按照URL查找会话,无论它在哪个Web服务器上。
答案 1 :(得分:1)
我认为这里存在多个REST问题,其中一些是因为您从根本上尝试通过HTTP实现SSH。我看到的问题包括:
(1)按服务器管理客户端状态 - 除非您持久保存当前连接(这看起来很奇怪),否则您违反了REST的无状态精神。
(2)将操作转移到连接上的“更新”,而不是对真实资源的操作。根据您的描述,如果您将连接本身用作资源,则建立的SSH连接上发生的操作似乎将建模为SSH连接的UPDATE。
当然,没有人会因为你的REST-ify而把你扔进监狱,但总的来说我确实同意你试图在一个圆孔中安装一个方形钉。
相反,我会问自己为什么这需要REST-ified。 SSH连接很好理解,可以通过各种方式在各方之间完成,而不会发明您描述的内容。事实上,如果您考虑为您的任务编写基于GUI的Web应用程序,您似乎正在尝试实现其中一个绿屏超过HTTP解决方案,这通常从未有过快乐的结局,所以我个人会避免它。