2014-10-29 120 views
1

我正在设计一个大型的报告数据集合的REST风格的API,我想通过一组复杂的参数,如下面的代码块。我在为这个端点使用POST和GET之间进行辩论。团队成员似乎赞成GET,但我不知道通过这个数据量作为GET参数,最好的办法,到目前为止是有一个GET参数称为像jsonparams,将有以下所有JSON编码的最佳方式REST风格的API设计的争论:复杂的查询宁静的端点

{ 
    "filters": 
    [ 
     { 
     "field": "metric-name", 
     "gt": (float/int), 
     "lt": (float/int) 
     }, 
     { 
     "field": "metric-name-2", 
     "gt": (float/int), 
     "lt": (float/int) 
     } 
    ], 
    "sort": 
    [ 
     { 
     "field": "metic-name", 
     "order": "ASC"/"DESC" 
     }, 
     { 
     "field": "metic-name-2", 
     "order": "ASC"/"DESC" 
     } 
    ] 
    "limit": 100, 
    "offset": 0 
} 
+0

可能的重复[什么时候应该使用GET或POST方法?他们之间有什么区别?](http://stackoverflow.com/questions/504947/when-should-i-use-get-or-post-method-whats-the-difference-between-them) – 2014-10-29 22:29:59

+0

这是一个比这更概念 – dismal 2014-10-29 23:04:25

回答

2

如果要将数据添加到资源或创建资源,请使用POST。 GET是获取已经存在的资源,而不是改变资源的状态。

如果使用基于疯狂的序列化的基于GET参数的请求进行某种percived简单操作的参数,那么您将不会接受REST。

现在,如果您仅检索资源(不创建),请使用GET。虽然我更喜欢人类可压缩的参数,但并不是必需的。如果你的情况是100%恢复,你可以整组编码成成一个巨大的编码PARAM字符串,但我建议做类似的东西,至少分裂出来有点改进的理智:

/resource?filters=urlencoded_filter_array&sort=urlencoded_sort_array&offset=0&count=100 

或者你可以去更明确,如:

/resource?filter1=urlencoded_filter_json&filter2=urlencoded_filter_json .... sort2=urlencoded_sort_json&offset=0&count=100 

或最后(我的最爱)完全明确设定爆发则params的

/resource?filter1_field=bah&filter1_gt=1.0&filter1_lt<2&filter2_field=boo&filter2_lt... 

我喜欢最后一个,因为没有encodein g /解码json,然后url编码整个json字符串。这种格式很容易解读访问日志和故障排除。它也是非常缓存的,即使参数顺序被改变了,一些代理缓存仍然可以工作,而在json对象中编码一些过滤器,如果它们被移动,它们看起来像完全不同的值,就代理而言。对我来说,这是最友好的(如果这是有道理的),即使前两个例子是很好的REST GET请求。

解析参数名称的附加工作并不是那么大惊小怪。一个简单的方法可以将json转换为参数字符串,另一个简单的方法可以从显式filter1_xyz格式中重新提供json对象的水合。

+0

你会如何解决复杂参数的问题? – dismal 2014-10-29 22:55:48

+0

@dismal如果你正在创建一个资源,你可以传递json对象作为帖子正文。 – Ray 2014-10-30 14:34:24

+0

@dismal查看我更新的答案。如果你没有改变任何东西,只是过滤结果,你可以使用get。 – Ray 2014-10-30 15:00:57

4

POST是用于任何未通过HTTP标准化的操作的方法。检索通过GET方法进行标准化,因此使用POST检索与潜在资源相对应的信息永远不会是RESTful。从理论上讲,无论你的URI变得多么复杂,你都应该使用GET。

但是,由于您正在执行的查询中没有单个资源,您可以执行GET操作,所以使用POST似乎很好,只要您知道缺点并且文档是清楚它。坦率地说,我认为使用POST比将该有效负载编码为JSON + base64并将其作为纯粹查询字符串发送纯粹得多。

使用POST的真正问题是当人们以避免或阻止使用真实URI的方式使用它时。这似乎不是你的问题,因为你有一个有效的URI集合,但你的查询的语义太复杂,不容易表达。

如果您决定使用GET,那就有一个问题。尽管HTTP规范没有对URI进行限制,但大多数实现都是这样做的,如果需要将所有这些参数作为查询字符串提供,您可能会达到此限制。在这种情况下,只要从应用程序中分离出来,就可以避免底层实现的局限性。做你想做的事的惯例是使用POST方法和上面描述的有效载荷,以及X-HTTP-Method-Override: GET标题。

+0

我打算和GET一样在Ray的回答中,希望我不会遇到任何URI限制! – dismal 2014-10-30 18:16:21

+0

正如我所说,理论上这是正确的做法。如果它被采用是因为它适用于你的情况,而不仅仅是纯粹主义,我完全赞成。 – 2014-10-31 02:05:36