我正在为我们的应用程序开发一个新的RESTful Web服务。
当对某些实体执行GET时,客户端可以请求实体的内容。如果他们想添加一些参数(例如排序列表),可以在查询字符串中添加这些参数。
或者,我希望人们能够在请求主体中指定这些参数。HTTP/1.1似乎并没有明确禁止这一点。这将允许他们指定更多信息,可能会更容易指定复杂的XML请求。
我的问题:
这完全是个好主意吗?HTTP客户端在GET请求中使用请求体时会遇到问题吗?
https://www.rfc-editor.org/rfc/rfc2616
根据XMLHttpRequest,它无效。根据标准:
4.5.6 send()方法客户send([正文=空])启动请求。可选参数提供请求身体如果请求方法是GET或HEAD,则忽略该参数。如果任一状态都不是,则引发InvalidStateError异常打开或设置send()标志。send(body)方法必须运行以下步骤:如果状态未打开,则引发InvalidStateError异常。如果设置了send()标志,则引发InvalidStateError异常。如果请求方法是GET或HEAD,请将body设置为null。如果body为空,则转到下一步。
虽然,我认为这不应该,因为GET请求可能需要大量的正文内容。
因此,如果您依赖浏览器的XMLHttpRequest,它很可能无法工作。
REST作为协议不支持OOP,Get方法就是证明。作为解决方案,您可以将DTO序列化为JSON,然后创建查询字符串。在服务器端,您将能够将查询字符串反序列化为DTO。
看看:
ServiceStack中基于消息的设计使用WCF构建基于RESTful消息的Web服务
基于消息的方法可以帮助您解决Get方法的限制。您可以将任何DTO作为请求主体发送
Nelibur web服务框架提供了您可以使用的功能
var client = new JsonServiceClient(Settings.Default.ServiceAddress);
var request = new GetClientRequest
{
Id = new Guid("2217239b0e-b35b-4d32-95c7-5db43e2bd573")
};
var response = client.Get<GetClientRequest, ClientResponse>(request);
as you can see, the GetClientRequest was encoded to the following query string
http://localhost/clients/GetWithResponse?type=GetClientRequest&data=%7B%22Id%22:%2217239b0e-b35b-4d32-95c7-5db43e2bd573%22%7D
您试图实现的目标已经用一种更常见的方法完成了很长时间,这种方法不依赖于在GET中使用有效负载。
您可以简单地构建特定的搜索中介类型,或者如果您希望更具RESTful,可以使用类似OpenSearch的方法,并将请求POST到服务器指示的URI,例如/search。然后,服务器可以生成搜索结果或构建最终URI并使用303重定向。
这具有遵循传统PRG方法的优点,有助于缓存中介缓存结果等。
也就是说,URI无论如何都是针对非ASCII的任何内容进行编码的,application/x-www-form-urlencoded和multipart/form数据也是如此。如果您打算支持ReSTful场景,我建议使用此格式,而不是创建另一种自定义json格式。