5

I'm building a Json REST API for my application, and have some doubts about the design itself. My application has organizations and also equipment which belongs to organizations. That would be an example of the organizations API:

/organizations:

Loads all the organizations from the application

/organizations/{id}:

Loads a specific organization by id

This seems quite clear. However now I want to access equipment, which is accessible by id or code. The id is unique for the application, whereas the code is unique per organization. Some choices:

/organizations/{id}/equipment:

Loads the equipment by organization. This seems quite clear to me

/organizations/{idOrg}/equipment/{idEquip}:

Equipment by id. Isn't the organization id quite redundant here?

/organizations/{idOrg}/equipment/code/{code}:

Seems it makes sense, but probably would be better to pass code as a parameter.

/organizations/{idOrg}/equipment?id={idEquip}:

Best choice?

/organizations/{idOrg}/equipment?code={code}:

Best choice?

In my opinion, the methods below look better just for grabbing equipment (even if the return a list, while the method is supposed to return a single value or nothing). However I still have more relations into equipment, which these methods don't seem proper to fit. For example how to extend the API to integrate the methods to load files for each equipment?


UPDATE

It should be considered that organizations are structured hierarchically, so we've got organization trees and if org1 contains org2 and one equipment belongs to org2, it also belongs to org1.

  • Please excuse my reading comprehension, but does an organization only have one equipment or can it have multiple equipments? – Alex Dec 1 '16 at 23:05
  • Hi @Alex, the organization-equipment relation is one to many. Regards – Xtreme Biker Dec 2 '16 at 5:35
  • @XtremeBiker are the equipment identifiers globally unique, or only unique within an org? – RubberDuck Dec 2 '16 at 10:46
  • 1
    @RubberDuck they're globally unique. – Xtreme Biker Dec 2 '16 at 11:02
  • 1
    Actually, I just noticed that Yogi covered what I wanted to point out here. "in case you want to return just an equipment with it's id, then you should have a separate api for it, something like - /equipments/{idEquip}" – RubberDuck Dec 2 '16 at 12:58
10

When considering REST it is important to understand and design it as you are taking actions against a resource at the location, and not like making a remote function call.

I understand you are in doubt with your design for "Equipment by id".

I would like to be the api call like this -

/organizations/{idOrg}/equipment/{idEquip}

Reasons being -

  • With this design, you are very clearly stating that you are looking for a particular equipment in an organization.

  • Now you can also call other verbs like PUT, DELETE etc. against the same resource and adhere to the REST principles. For example, you would call the same api with delete to delete this resource or call it with put to updated it and send the updated data in request body.

  • And as you said Id for organization looks redundant but actually it is not. What we are saying with this is that get me an organization with this id and give me its related entity i.e. an equipment. Probably, equipment in alone may not make sense to the API if any related information from organization is required. And in case you want to return just an equipment with it's id, then you should have a separate api for it, something like -

    /equipments/{idEquip}

  • Query string parameters are suggested when you further want to drill down the resources with filter, paging or sorting etc. For example -

    /organizations/{idOrg}/equipments/?type="heavy"

Update (for updated Q. and comments) - Sometimes it becomes difficult when we visualize our api design in terms of our code. To keep it simple, if an equipment is part of any organization, then the api should get that equipment, of course in relation to that particular organization.

To add a new equipment to org3 you will use put on org3 i.e. /organizations/3. To modify and equipment already in org3 you will use put on equipment i.e. /organizations/3/equipment/1. And if you need to add a new equipment independently, you would call post on equipment i.e. /equipment

You can also consider your object hierarchy to make it more intuitive and logical if required

Suggest to read this series on Restful Api design

| improve this answer | |
  • Thank you so much, you have provided quite useful info to me – Xtreme Biker Dec 1 '16 at 14:53
  • @XtremeBiker: Glad it helped. Updated my answer to include a link to a good series on designing restful apis. – Yogi Dec 1 '16 at 16:19
  • I still have some other doubts. Let's suppose that organizations keep a hierarchical structure (as it happens in the real life). Imagine we've got org1 which is the parent of org2 and org3. If the equip1 belongs to the org2, the way to access it would be /organizations/2/equipment/1. But also /organizations/1/equipment/1 should be valid I think, since equip1 is inside org1, after all. Also in order to move equip1 to org3, I understand a PUT in /organizations/3/equipment/1 should be done? – Xtreme Biker Dec 2 '16 at 11:05
  • @XtremeBiker - Sometimes it become difficult when we visualize our api in terms of our code. To keep it simple, if an equipment is part of any organization, then it should get that equipment, of course in relation to the organization. To add a new equipment to org3 you will use PUT on org3 i.e. /organizations/3. To modify and equipment already in org3 you will use PUT on equipment i.e. /organizations/3/equipment/1. You can also consider your object hierarchy to make it more intuitive and logical if required. – Yogi Dec 2 '16 at 11:33
  • @XtremeBiker, please don't put follow-up questions in comments, that’s just not the StackExchange way. Follow-up questions should be new questions, or edits to the original question. – Tim Grant Dec 2 '16 at 11:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.