许多在这里有一个友好的开发人员(有人说是宗教)约一个RESTful API GET请求是否应该返回所请求的资源的ID讨论。 让我们假设以下GET请求:
http://my.api.com/rest/users/23
目前这返回:
{"name": "Jim", "age": 40, "favoriteColor": "blue"}
需要注意的是“ID”从结果集失踪。
基本上有4个营这个问题作斗争。
CAMP#1:当呼叫者可以GET请求,他们已经知道的ID。 因此,结果集不应包括ID。 如果呼叫方在需要此数据,使UI编辑,然后呼叫者需要穿过的ID 23,也许添加构件{“ID”:23}手动到JSON。
在营#1人们还认为,在结果集中的ID的存在将表明,该值可以被修改,当然它不能哪个。
CAMP#2:如果没有ID,JSON结果集不能本身用于UI形式编辑/更新操作。 取而代之的是,AJAX回调机制需要负责绕过ID字段和手动添加这些结果集。 这似乎klunky而且容易出错。 该UI的家伙们正在做的结果集“感觉”的说法像它的丢失数据应该存在,即ID。
CAMP#3:这些人都关心的一致性。 如果我们曾经有通过API返回的用户对象的集合,这些对象必须包括ID。 因此,对于一致性,一个GET的单版本应还包括ID。
CAMP#4:这些人所提出的建议,对于一个用户的GET请求可以以超媒体或SelfLinks的形式,其将包括ID返回元数据。
这不是一个深奥的“谁是对的?” 的说法,无论是。 我们采取的办法,将决定我们的API的形状和影响的几个开发人员的工作负荷在新的几周。
这是见仁见智的问题,这是不是那种爱#1,看问题的。 在任何情况下,我会提供我的。
您正在返回一个对象或资源的状态表示。 该ID是表示的部分,并且因此应该被包括在JSON包。 这是资源的属性。 无论主叫知道ID与否并不特别密切的讨论。 CAMP#1是站不住脚。
你提出有关集合点是非常相关的。 是否有意义使用一个表示为检索-1的操作,并为检索-N操作另一种表示? 我想不是。
但是,您所面临的问题是更普遍的- 什么样的数据应该包括在被转移到客户端,以及在什么情况下的代表性? 在某些情况下,主叫方根本不关心性能的显著子集。 特别是在一个大组对象的被检索到的场景 - 在成本来传输数据相比,基础通信成本较大的 - 你想优化什么是运回。
所有足够成熟REST协议必须塑造返回的数据的能力。
举例来说,看到
- Facebook的图形API, http://developers.facebook.com/docs/reference/api/
- 在StackExchange API 2.0版 - 有一个“过滤器”对象,你可以通过精确地塑造获取返回的内容。
- CouchDB的API -对每一个观点,这决定了数据被退商品的地图功能。 它也有一个毯子查询参数,
include_docs
,其引导服务器包括完整的对象或只是元数据。 (在某些情况下,您可能希望只是数据,而不是实际的数据的数量。)
Facebook允许你明确指定所需的字段。
该stackexchange API是有趣的。 他们定义了一种全新类型的对象,以支持整形。 您可以使用API来定义一个“过滤器”,并将其保存在服务器端。 然后在你的查询您通过一个过滤器PARAM与过滤器的ID,而返回的对象表示包括在过滤器中指定的所有属性。 由于没有过滤你的字段的“默认”子集。 要获得“全域”你需要定义一个包容各方的过滤器。
你可以看到这个动作https://api.stackexchange.com/docs/answers
......具体见过滤器规范对话框。
还有就是做事情没有唯一正确的方法。 你需要平衡的“塑形”功能,您与开发成本,将使用该API的应用程序的需要支持的复杂性。
老问题,但自从我来到这里寻找的东西,在这里它去另一个观点:
首先,我认为URL应该是:
http://my.api.com/rest/Users/23
不
http://my.api.com/rest/getUsers/23
“获取”位于HTTP方法,而不是在URL。 它仅仅是命名,但有助于使事情更清晰,恕我直言。
如果你想一想,一个资源修改需要在相同的URL发生了PUT
PUT http://my.api.com/rest/Users/23
在这种情况下,客户需要跟踪的网址,而不是ID的。 如果资源返回一个ID字段没关系。 它是由客户端,以保持地图了它是从获得的。
如果你试图把一个resorce不同的URL,说“ http://my.api.com/rest/Users/24 ”,会出现几种情况:
1) http://my.api.com/rest/Users/24已经存在于服务器上,服务器接受资源作为更新
2) http://my.api.com/rest/Users/24不会在服务器和存在:
a)所述服务器接受用户被给unexisting资源(不推荐)b)该服务器接受一个PUT作为POST提供的ID(24)
在A + B,服务器将创建一个新的资源。
所以:
1)取决于你有多少信任你的客户,你应该建立一个“签入/签出”控制在服务器上,以避免覆盖一个资源与另一个(这是REST风格的?)
2)你不应该接受的客户创建一个ID(OK后http://my.api.com/rest/Users/ ,不http://my.api.com/rest/Users/24 ),你不应该接受提出以非现有资源。
编辑 :
所以我相信资源由其URL识别,而不是由ID。 或者,换句话说,资源ID是http://my.api.com/rest/Users/23 ,而不是23。
说得通?