Get one for multiple identifier

Not applicable

Hi everyone,

I have a resource with multiple unique identifier

For example /dogs, with id, name and dna is unique.

how should a RESTful design for get one id, name and dna looks like?

Some of my thought:

1. Using query string:

/dogs/{id}
/dogs?name={name}
/dogs?dna={dna}

This is not consistent, where /dogs/{id} return a single entity, the others return a collection (of one)

2. use a type parameter

/dogs/{id}?type={id|name|dna}

the type if not provided will be "id" by default.

this make it consistent, all return single entity if found and 404 if not found.

3. sub resource

/dogs/{id}
/dogs/name/{name}
/dogs/dna/{dna}

hmm, not RESTful ?

Thank you

0 6 273
6 REPLIES 6

I think you might be talking about a search. in which case the correct answer is to shape your API like this:

POST /search?q=SEARCH_GOES_HERE

The search can contain anything you like. It's up to you whether you want to translate the "filter on X" into a query param X, or wrap the entire search into a single query param.

An example of the former

POST /search?name=foo

An example of the latter:

POST /search?q="name = foo"

(Keep in mind you'd have to url-encode the "name = foo" part into

name%3Dfoo

or

%22name%3Dfoo%22 )

You are using the term "id" as one part of a set of data or parameters that uniquely identities an entity. But that's not how IDs work. IDs are identifiers. They are unique. You don't get to have multiple entities (dogs, reports, consumers, products) with the same ID. The id is the identifier. If the thing (data item) you are calling ID is not used as a unique identifier, then it has a confusing name and you should use a different name.

This API:

	GET /item/{item_id}

...should return exactly one item, the item identified by the item_id (its identifier).

If there is not exactly one thing that is identified by /item/{item_id}, then your URI model is not restful.

my id, name, dna are all unique in the dogs resource (maybe user would a better example, where user name is unique)

GET /item/{item_id}

return exactly one item, I would like to have the exact same thing for an endpoint that accept name / dna or whatever is unique in my model

unlike a search that return an collection (if apply to this case, a collection of one always)

I think #1 is good with a little bit of adjustment for consistency.

GET /dogs/{id}

should return a single entity.

GET /dogs 

with or without query params should return an array, even if just one.

I like to use "convenience" search queryparams as you've shown.

GET /dogs?name=scruffy

returns an array and should be consistent across all your collections.

I generally reserve the use of a search endpoint with a body to hold more complex searches or to keep special identifiers (e.g. SSN) out of the URL so they are not accidentally logged.

POST /dogs/search 
Content-Type: application/x-www-form-urlencoded 

name=scruffy&SSN=123456789

my consistency problem is they are all unique in the resource but

GET /dogs/{id}

return a single entity, 404 if not found

GET /dogs?name=scruffy

return an array of one if found, array of none if not found

Not applicable

Hi @Dino-at-Google @Kurt Kanaskie

What about this scenario

I have 3 operations on /dogs in which each identifier is unique (say "name" is actually "username" like on Instagram)

dogs by id "dogs/3" (int)
dogs by dog-name "dogs/ikea" (string)
dogs by DNA Sequence "dogs/07426eee-ffae-492f-9207-7b17b2bdee7d" (string)

This above example works / is easy enough to do as we have different data types that can help us.

But what if "id" MUST be a UUID (string) and not an INT, which means we end up with

dogs by id "dogs/a5a39952-1510-4dd2-8ecc-7f3914316e43" (STRING)
dogs by dog-name "dogs/ikea" (string)
dogs by DNA Sequence "dogs/07426eee-ffae-492f-9207-7b17b2bdee7d" (string)

How (or is there a way) does the application know if I am requesting a dog-id or dog-dna-sequence if I hit

dogs/0168e906-45d3-449d-ac88-cfe820322d2f

Or it somehow doesn't matter because it is unique (which doesn't make sense, but maybe actually it does)

dogs/0168e906-45d3-449d-ac88-cfe820322d2f (valid dog id = 200)

dogs/0168e906-45d3-449d-ac88-cfe820322d2f (invalid DNA sequence = 404)

Cheers

Hi @david12345 ,

If you want to have multiple identifiers for the same entity you could introduce a URN naming convention (https://tools.ietf.org/html/rfc2141) that essentially adds a namespace to your identifier to make it unambiguous.

GET /dogs/urn:name:scruffy
GET /dogs/urn:uuid:a5a39952-1510-4dd2-8ecc-7f3914316e43
GET /dogs/urn:dna:07426eee-ffae-492f-9207-7b17b2bdee7d