Exposing RESTful endpoints for a one to many relationships

Samiron picture Samiron · Mar 24, 2015 · Viewed 11k times · Source

Consider the following relationship between two resources

  • College has many Faculties
  • Faculty belong to a College

Obviously a Faculty is not a first class resource here.

Now I need endpoints for following operations.

  • Create a new faculty in this college this farm. One possible way to do this in two operations.
    • POST /faculties/
    • PUT /college/1/faculties
  • Remove a faculty from this college. Again two operations
    • GET /college/1/faculties: List of associated faculties. Each will contain a self url like /faculties/1.
    • DELETE /college/1/faculties/1: The url looks better but how to expose this url?
  • Add one or more faculties under that college.
    • PUT /college/1/faculties that accepts a complete list of faculties of this college.
  • Delete that particular sector entirely.
    • DELETE /sectors/1: Looks good but needs to take care of the cache of /faculties/1/sectors.

What would be a better approach in this case? I have read about exposing membership resources, but with that approach, if a college has 10 faculties, it will take 10 seperate http call to get all of those from the memberships.

Moreover, this is just one small part of the full relationship tree. To extend this further, say the system has

  • Faculties has many Departments
  • Department has many labs so on.

And besides, In RESTful architecture, the client should never populate the URLs.

Any suggestion?

Answer

Thierry Templier picture Thierry Templier · Mar 24, 2015

I wrote a post in the past on how OData implements such aspects (feature "navigation properties"). See this link: https://templth.wordpress.com/2014/12/08/updating-data-links-of-odata-v4-services-with-olingo/.

This other link could also give you some interesting hints since it describes at the end the URLs and corresponding payloads: http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/entity-relations-in-odata-v4.

I think that there are two cases you can leverage to minimize the number of request: working with reference or provide content. I mean if the resource detects (based on the content or a custom header) the sent content so it knows if it only needs to handle a reference (attachment only) or a content (creation and attachment).

I would see following possible requests for multiple cardinality (college -> faculties):

  • POST /faculties/: add a faculty with no attachment to a college
  • POST /college/1/faculties: attach a faculty to a college and eventually create it if not exist (based on sent content)
  • DELETE /college/1/faculties/?ref=/faculties/1 to detach a faculty from a college

Something that you could also consider is to put the reference to the college within the faculty (request POST /faculties). So you could attach element during its creation.

Otherwise doing this PUT /college/1/faculties aims to replace the whole representation so all faculties that are attached to a particular college.

You could also use a POST or a PATCH method to minize the number of request. You can have a look at these answers for more details: REST API - Bulk Create or Update in single request and How to Update a REST Resource Collection. Such approach allows you to create elements in one call and then attach them. It allows to gather processing on elements.

Hope I was clear and it helps you, Thierry