0

Let's say I have dogs and cats, they have color, weight and name. Each of the animal can be identified using only color, weight and name together and, of course, their colors, weights and names are not unique, meaning can have the same values. There might be some other animal types added in the future.

What URI would you use for CRUD operations in Web REST API service?

/api/v1/animals/dogs/black/12/jack    
/api/v1/animals/type/dogs/color/black/weight/12/name/jack
/api/v1/animals?type=dogs&color=black&weight=12&name=jack  

or something else?

Oleksi
  • 12,583
  • 4
  • 51
  • 76
  • I think this answers your question and I've personally found it works well. Optional parameters in the query string. Required parameters in the URL: http://stackoverflow.com/questions/4024271/rest-api-best-practices-where-to-put-parameters – dcaswell Oct 02 '13 at 03:19
  • @user814064, but why color, weight and name are optional? without them an animal can't be unique identified. –  Oct 02 '13 at 03:31
  • If they're required they go in the URL. – dcaswell Oct 02 '13 at 03:32

2 Answers2

1

To me

/api/v1/animals?type=dogs&color=black&weight=12&name=jack

makes the most sense. With RESTful APIs you are accessing resources, and the resource here is "animals". The other fields are really human interpret-able attributes, as opposed to a unique identifier for getting back a single animal.

To make it more clean, you might want to consider giving each animal a single identifier to retrieve the resource /api/v1/animals/{id} and treat the other API as a search.

Oleksi
  • 12,583
  • 4
  • 51
  • 76
  • `To make it more clean, you might want to consider giving each animal a single identifier to retrieve the resource /api/v1/animals/{id} and treat the other API as a search.` -- it's not possible in my case for some reason. –  Oct 02 '13 at 03:37
  • are you implying that `?type=dogs&color=black&weight=12&name=jack` optional? they are not because all of them needed to unique identify an animal. –  Oct 02 '13 at 03:50
  • I am not implying that they are optional. If they are required, you can return an appropriate error code if they are omitted from a request. I understand that those attributes are often used for optional fields, but in this case, I think it's more intuitive to do it this way, as opposed to putting them in the URL. – Oleksi Oct 02 '13 at 12:56
  • doesn't it make more sense to put them in the URL if they are required? –  Oct 02 '13 at 16:15
  • You could, but prefer making the resource (animal) more obvious by having them be attributes. You could include them in the URL if you want. – Oleksi Oct 02 '13 at 17:34
0

Updated:

An URL should be for specifying the ‘resources’ that the API is to manage.

The resource is ‘animals’ (cats/dogs/…) and they are uniquely identified by type/color/weight/name.

Before going into URL design, need to define the ‘business’ operations; otherwise, how the URL is designed has no relevant.

Assume you will need the following business operations

  • A) Create an animal
  • B) Get info of an animal
  • C) Get info of all or subset of animals
  • D) Update an animal

id still can be used (generated) if that provide benefit; otherwise, it can be kept at the server side and not exposed to the client. Either way it still works..

A) Create an animal

POST: /api/v1/animals/dogs/black/12/jack/
RETURN: id: <id>

OR

POST: /api/v1/animals/dogs 
BODY: {‘color’ : ‘black’, ‘name’ : ‘jack’, ‘weight’ : 12 } 
RETURN: id: <id> 

B) Get info of an animal

GET: /api/v1/animals/<id>/

OR

GET: /api/v1/animals/dogs/black/12/jack/

C) Get info of all or subset of animals

GET: /api/v1/animals/dogs/

OR

GET: /api/v1/animals/dogs/black/

D) Update an animal

PUT: /api/v1/animals/<id>
BODY: {‘name’ : ‘jackjunior’}

OR

PUT: /api/v1/animals/dogs/black/12/jack/
BODY: {‘name’ : ‘jackjunior’}

Happy designing!

Ming Chan
  • 1,868
  • 11
  • 21
  • your assumption that each animal has a unique id is wrong, read my question please. –  Oct 04 '13 at 12:42
  • @Grienders the ID is normally a *database construct* in order to uniquely identify a given entry. Not necessarily an identifier from your actual problem domain. Are you saying you don't have anything from your data source to uniquely identify a given entry? – Pete Oct 04 '13 at 18:59