Should a RESTful GET response return a resource's ID?

依然范特西╮ 提交于 2019-12-02 18:10:58

This is a matter of opinion, which is not the kind of Question that Stackoverflow loves to see. in any case, I will offer mine.

You are returning the representation of the state of an object or resource. The ID is part of that representation, and therefore ought to be included in the JSON packet. It is a property of the resource. Whether the caller knows the ID or not is not particularly germane to the discussion. CAMP #1 is on shaky ground.

The point you raise about collections is very relevant. Does it make sense to use one representation for the retrieve-1 operation, and another representation for the retrieve-N operation? I think not.

However, the issue you are confronting is more general - what data should be included in the representation that is transferred to clients, and under what circumstances? In some cases the caller simply does not care about a significant subset of the properties. Especially in scenarios where a large set of objects gets retrieved - where the cost to transmit the data is larger in comparison to the base communication cost - you'd like to optimize what is shipped back.

All sufficiently mature REST protocols have an ability to shape the returned data.

For examples, see

  • the Facebook Graph API, http://developers.facebook.com/docs/reference/api/
  • the StackExchange API v2.0 - there is a "filter" object you can pass to precisely shape what gets returned.
  • the CouchDb API - has a map function for every view, which determines what data gets returned. It also has a blanket query parameter, include_docs, which directs the server to include full objects or just metadata. (In some cases you might want only the count of the data, not the actual data.)

Facebook allows you to explicitly specify the fields you want.

The stackexchange API is interesting. They've defined an entirely new type of object to support the shaping. You can use the API to define a "filter" and save it on the server side. Then in your query you pass a filter param with the ID of the filter, and the returned object representations include all the attributes specified in the filter. With no filter you get a "default" subset of fields. To get "all fields" you need to define an all-inclusive filter.

you can see this in action at https://api.stackexchange.com/docs/answers

...and specifically see the filter specification dialog.


There is no single correct way to do things. You need to balance the complexity of the "shaping" feature you support with the cost to develop and the needs of the apps that will use the API.

noderman

Old question, but since I got here searching for something, here it goes yet another opinion:

First of all, I think the URL should be:

http://my.api.com/rest/Users/23

not

http://my.api.com/rest/getUsers/23

The "GET" lies on the HTTP method, not on the URL. It is just naming, but helps make thing clearer, IMHO.

If you think about this, a resource modification needs to happen in the same URL with a PUT

PUT http://my.api.com/rest/Users/23

In that case, the client needs to keep track of URLs, not IDs. It doesn't matter if the resource returns an ID field. It is up to the client to keep a map of where it was obtained from.

If you try to PUT a resorce to a different URL, say "http://my.api.com/rest/Users/24", a few scenarios would occur:

1) http://my.api.com/rest/Users/24 already exists on the server and server accepts the resource as an update

2) http://my.api.com/rest/Users/24 does not exist on the server and:

a) the server accepts that a User is providing an ID ( 24 ) to a unexisting resource (not recommended) b) the server accepts a PUT as a POST

In a + b, the server would create a new resource.

So:

1) Depending on how much you trust your client, you should probably create a "check-in/check-out" control on the server to avoid overwriting one resource with another (is this RESTful?)

2) You should not accept clients creating IDs (OK to post http://my.api.com/rest/Users/, not http://my.api.com/rest/Users/24 ) and you should not accept PUTs to non-existing resources.

EDIT:

So I believe the resource is identified by its URL, not by the ID. Or, in other words, the resource ID is http://my.api.com/rest/Users/23, not 23.

Makes sense?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!