此处的一些开发人员正在就 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。 Camp#1中的人员也认为结果集中ID的存在表明该值可以被修改,当然它不能修改。
CAMP#2:如果没有ID,JSON结果集本身不能用于UI表单中的编辑/更新操作。相反,AJAX回调机制需要负责传递ID字段并手动将这些字段添加到结果集中。这似乎很笨拙且容易出错。 UI人员提出的结论是,结果集“感觉”就像缺少应该存在的数据,即ID。
CAMP#3:这些人关心的是一致性。如果我们有API返回的用户对象集合,这些对象必须包含ID。因此,为了保持一致性,GET的单例版本还应包含ID。
CAMP#4:这些人建议用户的GET请求可以返回包含ID的HyperMedia或SelfLinks形式的元数据。
这不是一个深奥的“谁是对的?”争论,或者。我们采用的方法将决定我们的API的形状,并影响几个开发人员在新的几周内的工作量。
答案 0 :(得分:15)
这是一个意见问题,这不是Stackoverflow喜欢看到的问题。无论如何,我会提供我的。
您将返回对象或资源状态的表示形式。 ID是该表示的一部分,因此应该包含在JSON数据包中。它是资源的属性。呼叫者是否知道ID并不特别与讨论密切相关。 CAMP#1在摇摇欲坠的地面上。
你提出的关于收藏的观点非常重要。为retrieve-1操作使用一个表示是否有意义,以及retrieve-N操作的另一个表示是否有意义?我想不是。
但是,您遇到的问题更为一般 - 应该在转移到客户端的表示中包含哪些数据,以及在什么情况下?在某些情况下调用者根本不关心属性的重要子集。特别是在检索到大量对象的情况下 - 与基本通信成本相比,传输数据的成本更高 - 您希望优化发回的内容。
所有足够成熟的REST协议都能够对返回的数据进行整形。
例如,见
include_docs
,它指示服务器包含完整对象或仅包含元数据。 (在某些情况下,您可能只需要数据计数,而不是实际数据。)Facebook允许您明确指定所需的字段。
stackexchange API很有意思。他们定义了一种全新的对象来支持整形。您可以使用API来定义"过滤器"并将其保存在服务器端。然后在您的查询中传递带有过滤器ID的过滤器参数,返回的对象表示包括过滤器中指定的所有属性。没有过滤器,你会得到一个"默认"字段子集。获得"所有领域"你需要定义一个包罗万象的过滤器。
您可以在https://api.stackexchange.com/docs/answers
看到这一点...并且具体参见过滤器规格对话框。
没有一种正确的做事方式。你需要平衡"塑造"的复杂性。您支持开发成本和将使用API的应用程序的需求。
答案 1 :(得分:2)
老问题,但是因为我到这里寻找一些东西,这里又有另一种意见:
首先,我认为网址应为:
http://my.api.com/rest/Users/23
不
http://my.api.com/rest/getUsers/23
“GET”位于HTTP方法上,而不是URL上。它只是命名,但有助于使事情更清晰,恕我直言。
如果您考虑这一点,则需要在具有PUT的同一URL中进行资源修改
PUT http://my.api.com/rest/Users/23
在这种情况下,客户端需要跟踪URL,而不是ID。资源是否返回ID字段无关紧要。客户需要保留从中获取的地图。
如果您尝试将重新分配到其他网址,例如“http://my.api.com/rest/Users/24”,则会出现以下几种情况:
1)服务器上已存在http://my.api.com/rest/Users/24,服务器接受该资源作为更新
2)服务器上不存在http://my.api.com/rest/Users/24并且:
a)服务器接受用户正在向未使用的资源提供ID(24)(不推荐) b)服务器接受PUT作为POST
在a + b中,服务器将创建一个新资源。
所以:
1)根据您对客户端的信任程度,您应该在服务器上创建“签入/签出”控件,以避免用另一个资源覆盖一个资源(这是RESTful吗?)
2)您不应该接受创建ID的客户(可以发布http://my.api.com/rest/Users/,而不是http://my.api.com/rest/Users/24),您不应该接受PUT到不存在的资源。
修改强>:
所以我认为资源是由其URL标识的,而不是由ID标识的。或者,换句话说,资源ID是http://my.api.com/rest/Users/23,而不是23。
有道理吗?