复杂的应用
我努力将RESTful原则应用于我正在开发的新Web应用程序。 特别是,这是一个RESTful的想法,每个HTTP请求都应该携带足够的信息,以便接收者处理它,使其与HTTP的无状态特性完全一致。
该应用程序允许用户搜索药物。 搜索接受过滤器作为输入,例如,退回停用的药品,包括免费治疗等..等等。 总共有大约30个可以应用的过滤器。
此外,可以输入患者详细信息,包括患者年龄,性别,当前药物等。
如果所有这些信息都包含在每一个请求中,那么要安定下来? 这似乎给网络带来了巨大的开销。 另外,URL长度的限制,至少对于GET来说,是不可行的?
“作为资源过滤”是一个完美的机会。
您可以将过滤器定义放入过滤器资源,并且可以返回过滤器ID。
PUT是幂等的,所以即使过滤器已经在那里,你只需要检测你之前看过过滤器,所以你可以返回过滤器的正确ID。
然后,您可以将筛选参数添加到其他请求中,并且可以获取用于查询的筛选器。
GET /药物?filter = 1234&page = 4&pageize = 20
我会通过某种规范化过程来运行原始过滤器,只是为了有一个规范化的集合,例如,过滤器“firstname = Bob lastname = Eubanks”与“lastname = Eubanks firstname = Bob”相同。 这只是我而已。
唯一真正关心的是,随着时间的推移,您可能需要淘汰一些过滤器。 如果有人用丢失或过时的过滤器发出请求,您可以简单地将请求误报。
编辑回答问题...
我们从基本面开始。
简单地说,你想指定一个用于查询的过滤器,但是这些过滤器(可能)涉及并且很复杂。 如果是简单/药物/ 1234,这不会是一个问题。
实际上,您始终需要将过滤器发送到查询。 问题是如何表示该过滤器。
REST系统会话等基本问题在于它们通常是“带外”管理的。 当你说,去创建一种药物时,你可以把它放在药物资源上,然后你可以得到一个参考资料。
通过一个会话,你可以(通常)取回一个cookie,或者其他一些令牌来表示该会话。 如果您对药物资源的PUT也创建了会话,那么实际上,您的请求创建了两种资源:药物和会话。
不幸的是,当您使用类似cookie的东西,并且您的请求需要该cookie时,资源名称不再是资源的真实表示。 现在它是资源名称(URL)和cookie。
因此,如果我在名为/ medications / search的资源上执行GET操作,并且Cookie代表一个会话,并且该会话恰好有一个过滤器,那么可以看到该资源名称/ medications / search是如何生效的,根本没有用。 由于Cookie和会话及其中的过滤器的副作用,我没有获得有效使用所需的全部信息。
现在,您可以重写名称:/ medications / search?session = ABC123,将cookie嵌入到资源名称中。
但是现在你接受典型的会话合同,特别是他们是短命的。 所以,这个命名的资源不太有用,长期而言,没有用处,只是用处不大。 现在,这个查询给了我有趣的数据。 明天? 可能不会。 我会得到关于会话消失的一些令人讨厌的错误。
另一个问题是会话通常不作为资源进行管理。 例如,它们通常是副作用,通过GET / PUT / DELETE显式管理。 会话也是Web应用程序状态的“垃圾堆”。 在这种情况下,我们只是希望会话能够正确填充此请求所需的内容。 我们其实并不知道。 再次,这是一个副作用。
现在,让我们稍微思考一下。 让我们使用/ medications / search?filter = ABC123。
显然,随便,这看起来完全相同。 我们只是将名称从“会话”更改为“过滤器”。 但是,正如所讨论的,在这种情况下,过滤器是“第一类资源”。 它们需要被创建,管理等,就像药物,JPEG或系统中的任何其他资源一样。 这是关键的区别。
当然,你可以把“会议”当作第一类资源,创造它们,直接把东西放入其中,等等。但是你可以看到,至少从清晰的角度来看,“第一类”会话并不是真的这是一个很好的抽象。 使用会话,就像去清洁工,交出你的整个钱包或公文包。 “是的,机票在那里,挖出你想要的东西,给我我的衣服”,特别是与像过滤器一样明确的东西相比。
所以,你可以看到在30,000英尺的情况下,过滤器和会话之间的情况没有太大的区别。 但是当你放大时,它们是完全不同的。
通过筛选器资源,您可以选择永远将它们永久化。 你可以过期他们,你可以做任何你想要的。 会话往往具有预先设想的语义:短暂的生活,连接的持续时间等。过滤器可以具有任何你想要的语义。 它们与会话中的完全分开。
如果我这样做,我将如何使用过滤器?
我会假设我真的不关心过滤器的内容。 具体来说,我怀疑我会查询“所有过滤器的名字搜索”。 在这个时候,它似乎是无趣的信息,所以我不会围绕它设计。
接下来,我会正常化过滤器,就像我上面提到的那样。 确保等效的过滤器真的是等效的。 你可以通过对表达式进行排序,确保字段名都是大写字母或其他。
然后,我会将过滤器存储为XML或JSON文档,无论哪个更适合应用程序。 我会给每个过滤器一个唯一的键(自然),但我也会用过滤器为实际文档存储一个散列。
我会这样做,以便能够快速找到过滤器是否已经存储。 由于我正在规范化,所以我“知道”逻辑上等价的过滤器的XML(比如说)是相同的。 所以,当有人去PUT,或者插入一个新的过滤器时,我会检查哈希以查看它是否已经存储过。 我可能会返回多个哈希(当然,哈希可能会发生碰撞),所以我需要检查实际的XML有效负载以查看它们是否匹配。
如果过滤器匹配,则返回对现有过滤器的引用。 如果没有,我会创建一个新的并返回。
我也不会允许过滤器更新/ POST。 由于我正在分发对这些过滤器的引用,因此我会让它们不可变,以便引用可以保持有效。 如果我想通过“角色”过滤一个过滤器,例如“获取所有过期药物过滤器”,那么我会创建一个“名为过滤器”资源,将名称与过滤器实例相关联,以便实际的过滤器数据可以更改,但名称保持不变。
请注意,在创作过程中,您处于竞争状态(两个请求尝试制作相同的过滤器),因此您必须对此进行说明。 如果你的系统有很高的过滤量,这可能是一个潜在的瓶颈。
希望能够为你解决这个问题。
如果所有这些信息都包含在每一个请求中,那么要安定下来?
不可以。如果看起来您的服务器正在发送(或接收)太多的信息,则可能有一个或多个您尚未识别的资源。
设计RESTful系统的第一步也是最重要的一步是识别并命名您的资源。 你会如何为你的系统做这件事?
从你的描述中,下面是一组可能的资源:
然后你可以寻找资源之间的关系;
具体细节可能不适合您的特定问题,但想法很简单:在您的资源之间建立一个关系网络。
此时,考虑URI结构可能会有所帮助,但请记住,REST API必须由超文本驱动:
# view all Recommendations for the patient
GET http://server.com/patients/{patient}/recommendations
# view all Recommendations for a Medication
GET http://servier.com/medications/{medication}/recommendations
# add a new Recommendation for a Patient
PUT http://server.com/patients/{patient}/recommendations
由于这是REST,因此您将花大部分时间来定义用于在客户端和服务器之间传输资源表示的媒体类型。
通过公开更多资源,可以减少每次请求期间需要传输的数据量。 还要注意URI中没有查询参数。 服务器可以具有状态性,因为它需要全程跟踪,并且每个请求都可以完全独立。
REST适用于API,而不是(典型的)应用程序。 不要试图将基本上有状态的交互转化为无状态模型,只是因为你在维基百科上阅读了它。
如果所有这些信息都包含在每一个请求中,那么要安定下来? 这似乎给网络带来了巨大的开销。 另外,URL长度的限制,至少对于GET来说,是不可行的?
参数的大小通常与服务器发送资源的大小相比无关紧要。 如果您使用的这些大参数是网络负担,请将它们放在服务器上一次,然后将它们用作资源。
URL长度没有重大限制 - 如果您的服务器有这样的限制,请升级它。 无论如何,它可能已经有几年了,并且充满了安全漏洞。
链接地址: http://www.djcxy.com/p/21945.html上一篇: complex applications