Paul
Paul

Reputation: 3087

Returning objects with multiple types in a RESTful way

I'm currently designing an API to handle requests from mobile clients. To achieve some degree of decoupling between backend and client I would like to define the webservices in a RESTful way. The challenge that I am facing is returning multiple objects with different types for a single call.

Lets say we have the following Model:

As far as i understand REST, if I now want to display all the boats and sheds in the harbour I would send two requests:

/harbours/{harbour_id}/boats Returning a list of all boats. Boats in a shed would contain an id linking to the shed they are in

/harbours/{harbour_id}/sheds Returning a list of all sheds

As I want to use the web service in a mobile scenario, it would be ideal to combine these two calls into one. This could then either return the list of boats with the shed object nested within, or both object types side by side:

/harbours/22/boats

[
   {
      "id":1,
      "boatName":"Mary",
      "boatShed":{
         "id":1,
         "shedName":"Dock 1",
         "capacity":55
      }
   },
   {
      "id":2,
      "boatName":"Jane",
      "boatShed":{
         "id":1,
         "shedName":"Dock 1",
         "capacity":55
      }
   }
]

or

/harbours/22/boats

{
   "boats":[
      {
         "id":1,
         "boatName":"Mary",
         "boatShedId":1
      },
      {
         "id":2,
         "boatName":"Jane",
         "boatShedId":1
      }
   ],
   "sheds":[
      {
         "id":1,
         "shedName":"Dock 1",
         "capacity":55
      }
   ]
}

My question now is, which of these ways is closer to the idea behind REST, or is it not RESTful at all?

Upvotes: 2

Views: 4213

Answers (2)

Max Ivanov
Max Ivanov

Reputation: 6561

As @Tarken mentioned /boats request should not return sheds in the top level (since the url assumes you're asking for collection of resource Boat)

If you have relations defined as follows

Harbour:
    boats: Boat[]
    sheds: Shed[]

Shed:
    boats: Boat[]

Boat:
    harbour: Harbour
    shed: Shed

/harbours/ID then returns a Harbour representation with boats and sheds relation set.

{
  boats: 
  [
    { Boat },
    { Boat },
    ..
  ],
  sheds: 
  [
    { Shed },
    { Shed },
    ..
  ],
  ...
}

Nothing is against restful principles here - the url uniquely identifies a resource and resource representation can be anything, with links to other resources as well.

Upvotes: 1

Madhusudan Joshi
Madhusudan Joshi

Reputation: 4476

Create a Harbour model which contains both Boat Shed and Boat information. If i am implementing the service in Java, then i would have done something like this :

class Boat{
...
}

class BoatShed{
...
}

class Harbour{
List<Boat> boats;
List<BoatShed> boatSheds;
...
}

You can create an API like /api/harbours/{harbourId}.

As per your question you want to display all the boats and sheds in the harbour, say id=1234, you can make a request like this :

GET /api/harbours/1234

This will return list of Boats and list of Boat Sheds like this:

{
"boats":[
  {
     "id":1,
     "boatName":"Mary",
     "boatShedId":1
  },
  {
     "id":2,
     "boatName":"Mary2",
     "boatShedId":2
  }
],
"sheds":[
  {
     "id":1,
     "shedName":"Dock 1",
     "capacity":55
  },
  {
     "id":2,
     "shedName":"Dock 2",
     "capacity":50
  }
  ]
}

EDIT As you want to get boats and Sheds side by side by sending one request, the api/hourbours/{id} looks good according to REST API design principles.

Getting all sheds while requesting for boats is not in accordance with ideal REST API design, but if you want to achieve the same you can d the following.

If you want that way, then first one /api//harbours/{id}/boats looks good to me.

Upvotes: 0

Related Questions