Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

REST approach to GET on resource via either surrogate id or business id

We have some entities that have both a unique business id (e.g. "my-unique-name") and also have an internal UUID (e.g. aa54-342-dffdf-55445-effab). Whats is a good way to provide a REST URI that can return the resource using either method.

Approach 1 - have two resource URLs (ugly!!!):

/foo-by-id/my-unique-name

/foo-by-uuid/aa54-342-dffdf-55445-effab

Approach 2 - always use a query parameter (even though it returns a single item...seems un-rest-lke)

/foo?id=my-unique-name

/foo?uuid=aa54-342-dffdf-55445-effab

Approach 3 - have the web service figure out whether the {id} is a UUID or not (this could get error prone, but in all likihood would work just fine...

Approach 4 - use the UUID, allow business id as a query parameter (don't know if this would work)

/foo?id=my-unique-name

/foo/aa54-342-dffdf-55445-effab

Any thoughts are appreciated.

like image 634
HDave Avatar asked Jan 06 '12 22:01

HDave


People also ask

How are resources identified in rest?

REST Server simply provides access to resources and REST client accesses and modifies the resources. Here each resource is identified by URIs/ Global IDs. REST uses various representations to represent a resource where Text, JSON, XML. The most popular representations of resources are XML and JSON.

What is resource ID in REST API?

Each REST API resource can be accessed by using a Uniform Resource Identifier (URI). The URI must contain the correct connection information to successfully call the API. The connection information consists of the host name where the web management service is running, and the port number that the service is using.

DOES THE REST API ID change?

If the PUT results in the server moving the underlying resource, the ID can change.

How do you create a REST resource?

Resources are typically created by sending a POST request to the parent collection resource. This creates a new subordinate resources with a newly generated id. For example, a POST request to /projects might be used to create a new project resource at /projects/123.


2 Answers

I would use something similar to option 4. Use the UUID in the path segment as the single resource URL. Use the alternate URL as a kind of search URL

e.g.

GET /foo?name=my-unique-name

303 See Other
Location: http://example.org/foo/aa54-342-dffdf-55445-effab

You don't want to have two URLs that both return a 200 with the same resource. That causes cache pollution.
And now you are free to use the GET "search style" URL for other types of searches.

GET /foo?account=other-unique-value

303 See Other
Location: http://example.org/foo/aa54-342-dffdf-55445-effab

or you could even search on non-unique stuff.

GET /foo?country=a-non-unique-value

200 OK
Content-Type: application/vnd.hal+xml

<resource href="http://example.org/foo?country=a-non-unique-value">
   <resource rel="urn:acme:foo" href="http://example.org/foo/aa54-342-dffdf-55445-effab"/>
   <resource rel="urn:acme:foo" href="http://example.org/foo/ba54-299-weras-55445-effab"/>
   <resource rel="urn:acme:foo" href="http://example.org/foo/ca54-743-werre-23434-effab"/>
<resource>
like image 122
Darrel Miller Avatar answered Sep 27 '22 16:09

Darrel Miller


Pick one as canonical, and 307 redirect the other to it. If you don't, then you run the risk of the two URI's returning different data because they have been cached at different times or lifetimes. By redirecting from one to the other, you allow a PUT, POST, or DELETE request to invalidate the cache of a single, canonical URI. Use 307 instead of 302 so that "historic" clients don't change POST to GET. I'd recommend Approach 1, having the UUID redirect to the business ID just because it's prettier.

like image 41
fumanchu Avatar answered Sep 27 '22 16:09

fumanchu