我正在创建一个新的REST服务。
在Java中的不同REST实现中,传递参数的标准是什么?您可以将参数配置为路径的一部分或请求参数的形式。例如:
路径参数: http://www.rest.services.com/item/b
请求参数: http://www.rest.services.com/get?item=b
有人知道每种方法传递参数的优缺点吗?似乎将参数作为路径的一部分更符合REST协议的概念。也就是说,单个位置表示唯一的响应,对吗?
我正在创建一个新的REST服务。
在Java中的不同REST实现中,传递参数的标准是什么?您可以将参数配置为路径的一部分或请求参数的形式。例如:
路径参数: http://www.rest.services.com/item/b
请求参数: http://www.rest.services.com/get?item=b
有人知道每种方法传递参数的优缺点吗?似乎将参数作为路径的一部分更符合REST协议的概念。也就是说,单个位置表示唯一的响应,对吗?
通常情况下,路径会被缓存,而参数则不会被缓存。
因此...
GET /customers/bob
对比
GET /customers?name=bob
前者更可能被缓存(假设使用了适当的头信息等),而后者则很可能不会被缓存。
简短概括: 也许你都需要。
第42项存在:
GET /items/42
Accept: application/vnd.foo.item+json
--> 200 OK
{
"id": 42,
"bar": "baz"
}
GET /items?id=42
Accept: application/vnd.foo.item-list+json
--> 200 OK
[
{
"id": 42,
"bar": "baz"
}
]
第99个项目不存在:
GET /items/99
Accept: application/vnd.foo.item+json
--> 404 Not Found
GET /items?id=99
Accept: application/vnd.foo.item-list+json
--> 200 OK
[
]
/items/{id}
返回一个 item
,而 /items?id={id}
则返回一个 item-list
。item-list
中只有一个元素,为了保持一致性 (而不是单个元素本身),仍将返回一个包含单个元素的列表。id
是一个唯一的属性。如果我们根据其他属性进行筛选,则仍然可以以完全相同的方式工作。OK
,并且仍包含一个列表(尽管为空)。仅因为我们请求一个包含不存在的项的筛选列表,并不意味着列表本身不存在。由于它们非常不同且独立有用,您可能都需要。客户端将希望区分所有情况(例如列表是否为空,或者列表本身不存在,在这种情况下,您应该为 /items?...
返回404)。
免责声明:这种方法绝不是“标准的”。但对我来说非常有意义,所以我感觉值得分享。
PS:将项目集合命名为“get”是一种编码上的问题;最好使用“items”或类似名称。
你提供的第二个“请求参数”的例子是不正确的,因为“get”包含在路径中。GET是请求类型,不应该作为路径的一部分。
有四种主要类型的请求:
GET PUT POST DELETE
GET请求应该始终能够在没有任何请求体信息的情况下完成。此外,GET请求应该是“安全”的,这意味着请求不会修改任何重要数据。
除了上面提到的缓存问题之外,URL路径中的参数往往是必需的或者被期望的,因为它们也是路由的一部分,而在查询字符串中传递的参数更加变化,不影响请求路由到应用程序的哪个部分。虽然你可能还可以通过URL传递一个可变长度的参数集:
GET somedomain.com/states/Virginia,California,Mississippi/
一本关于这个主题的入门好书是"Restful Web Services"。但我要提醒你准备略过一些冗余信息。
http://www.rest.services.com/items/b?sort=ascending;page=6
这是一个很好的基本问题。我最近得出结论,要避免使用路径参数。它们会导致模糊的资源解析。URL 基本上是运行在服务器某处的代码片段的“方法名”。我不喜欢将变量名与方法名混合在一起。你的方法名称显然是“customer”(在我看来,这是一种糟糕的方法名称,但 REST 人士喜欢这种模式)。传递到该方法的参数是客户的姓名。查询参数对此非常有效,如果需要,甚至可以缓存此资源和查询参数值。
没有实际的 IT 客户资源。可能在以客户命名的文件夹下没有名为客户的文件。这是一个执行某种数据库事务的 Web 服务。“资源”是您的服务,而不是客户。
对 REST 和 Web 动词的着迷让我想起了面向对象编程的早期,我们试图将代码塞入物理对象的虚拟表示中。然后我们意识到,对象通常是系统中的虚拟概念。如果正确使用,面向对象编程仍然很有用。REST 也很有用,如果你认识到 RESTful 资源是服务,而不是对象。