我正在设计一个(或多或少)RESTful内部Web服务,在ASP.NET和IIS上运行.我希望客户端能够在访问大型条目集合时将查询详细信息传递给服务器,使用JSON以已知方式描述查询.问题是发送到服务器的查询会很复杂; 它们可能包括聚合,过滤,映射 - 实质上是LINQ查询运算符支持的任何内容.这将导致表示查询的相对较大的JSON对象.
我面临的冲突是,虽然查询在语义上是GET在REST的世界中,但是没有标准化的方法将大块数据传递给Web服务器GET.我想出了一些解决这个问题的方法.
选项1:在GET请求正文中发送查询对象.
GET /namespace/collection/ HTTP/1.1
Content-Length: 22
{ /* query object */ }
Run Code Online (Sandbox Code Playgroud)
显然,这是非标准的,并且某些软件可能会阻塞GET具有正文的请求.(或者更糟糕的是,简单地剥离主体并在没有它的情况下处理请求,这将导致服务器返回不正确的结果集.)
选项2:使用非标准HTTP动词(可能QUERY)而不是GET.
QUERY /namespace/collection/ HTTP/1.1
Content-Length: 22
{ /* query object */ }
Run Code Online (Sandbox Code Playgroud)
虽然这不完全适合REST模式,但似乎(对我而言)是一种安全的替代方案,因为其他软件(例如使用WebDAV的任何软件)似乎使用非标准HTTP动词并取得了足够的成功.
选项3:将查询对象放在非标准HTTP标头中.
GET /namespace/collection/ HTTP/1.1
ProjectName-Query: { /* query object */ }
Run Code Online (Sandbox Code Playgroud)
此选项将请求保持为 GET,但需要填充HTTP头中可能非常大的对象.我理解一些软件对HTTP标头设置任意长度限制,因此如果对象太大,这可能会导致问题.
选项4:使用POST动词并提供备用端点进行查询.
POST /namespace/collection/query HTTP/1.1
Content-Length: 22
{ /* query object */ }
Run Code Online (Sandbox Code Playgroud)
因为它使用标准动词而没有标准标题,所以保证此方法适用于所有场景.唯一的问题是它偏离了RESTful架构,我试图尽可能保持一致.
这些选项都不是正确的.我想知道的是哪种方式对我正在写的服务最有意义; 它是一个内部Web服务(它永远不会暴露给公众),但它可以通过各种网络安全应用程序(防火墙,内容过滤器等)访问,我想坚持已知的开发风格,标准和架构尽我所能.