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.
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.
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.
If the PUT results in the server moving the underlying resource, the ID can change.
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.
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>
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With