Rest 使用GET管理复杂数据

Rest 使用GET管理复杂数据,rest,http,asp.net-web-api,Rest,Http,Asp.net Web Api,我经常发现在不发送JSON正文的情况下很难管理复杂的GET请求。URL参数就是不能解决这个问题。如果我设法找到一个解决URL参数的方法,那么它通常会增加更多的复杂性和混乱 我不是一名web开发人员,我没有做过任何大型应用程序,但即使是小型应用程序,我也有这样的请求: { page: { batch: 10, current: 1 } , sort: { _id: -1 } , project: {history: 0, attach: 0} , filter: { status: "new"}

我经常发现在不发送JSON正文的情况下很难管理复杂的GET请求。URL参数就是不能解决这个问题。如果我设法找到一个解决URL参数的方法,那么它通常会增加更多的复杂性和混乱

我不是一名web开发人员,我没有做过任何大型应用程序,但即使是小型应用程序,我也有这样的请求:

{ page: { batch: 10, current: 1 }
, sort: { _id: -1 } 
, project: {history: 0, attach: 0}
, filter: { status: "new"}
}
这是一个没有数组的简单请求。数组只是让这个问题变得更加严重

所以,我的问题是,在没有JSON主体的情况下,如何管理复杂的GET请求?我做错了什么/想错了什么?为什么我们不能把身体和身体联系起来

是的,我可能可以使用URL参数发送此请求,但这会使生活变得更加困难,尤其是当您需要发送筛选器、分页等等时

我厌倦了所有的困难,把这样的GET请求改为POST。
我知道这是错误的(因此提出了这个问题),但这感觉就像是我肩上卸下的巨大负担

我想这两个链接可以给你一些提示:

我认为这取决于您希望在请求中处理的查询的复杂性。您可以利用查询参数来实现这一点,但如果使用这些参数设计查询太复杂,则可以使用方法
POST
,其中包含描述它的内容

您可以查看OData管理此操作的方式(尤其是查询参数
$filter
$count
$orderby
$skip
,以及
$top
)。有关详细信息,请参阅此链接:

希望它能帮助你, 蒂埃里

我厌倦了所有的困难,把这些请求改成了GET 邮递我知道这是错误的(因此这个问题),但它感觉像是巨大的 卸下我的肩膀

那根本不是真的。POST是用于执行任何未被HTTP标准化的操作的方法。GET是标准化的检索工具,所以原则上你可以说用POST做你应该用GET做的事情是错误的,但是有一个陷阱

没有任何东西可以阻止您在GET请求中发送有效负载。RFC7231说GET负载没有定义的语义,所以只要对它进行文档化,就可以包含它。因为没有标准语义,所以必须为API生态系统确定统一的接口。然而,最大的问题是,尽管您的应用程序可以很好地处理GET负载,但是您和客户机之间的许多HTTP实现可能都不能。可能客户端或HTTP服务器忽略了它,或者缓存服务器不会缓存它,等等

考虑到这一点,POST也是一种用来避免中断实现的方法。例如,许多公共API有一个
X-HTTP-Method-Override
头,允许您使用POST方法发出PUT或补丁请求,指定头中要使用的实际方法,以防中间的一些实现不理解PUT和补丁


所以,在你的位置上,我会简单地使用POST并记录我是如何使用它的,就像你已经做的那样;或者,我会在GET请求上接受一个有效负载,并允许客户端使用POST发出带有有效负载的请求,以防某些实现被破坏,并为此设置一个覆盖头。

POST请求有什么问题?@Veselin Vasilev POST没有问题。我就是这么用的。但是用POST请求对象列表感觉是错误的。因此,我的大多数API最终都是“获取更少”。拍摄结构化的JSON然后摆弄笨拙的URL参数要容易得多。使用
POST
请求获取资源违反了REST原则。对分页/筛选请求使用
POST
是RPC over HTTP。@LutzHorn这是错误的。根据这种推理,POST的任何使用都是RPC。检查我下面的答案。@PedroWerneck不,那不是我写的。
POST
有一些有效用法,例如创建集合资源的新子项(服务器为其分配完整URL)。确定。这个答案让我对自己的工作有了一些信心。我将继续使用POST进行复杂的查询,不会对此感到内疚/错误。谢谢。你提到了统一界面。使用主体的
GET
请求的统一接口是什么?如果两个这样的请求只在负载上不同,它们是针对相同的资源还是针对不同的资源?正如我所说的,GET with a body没有定义的语义,所以这取决于您。当我使用它时,我认为身体与QuiSQL字符串参数具有相同的含义,但是允许更复杂。缓存也可能被禁用,因为大多数缓存实现将忽略GET主体。