REST Design – Multiple Calls vs Returning All Data in One Call

rest

I am trying to build a rest API for an android app. Suppose I have a users table with (id, name, email) and a songs table with (id, song_name, album) and a rich join association between them as streams having (user_id, song_id, listen_count). I want to fetch details about all the streams and show it in the app as a list. The list would be showing the song name, album name, user name and listen count. I see three plausible options –

  1. GET to /streams and fetch a list of all the song_ids and user_ids. Then make GET to /user/:id and /song/:id for each user and song id to get the user and song information.
  2. GET to /streams and fetch a list of all the user_ids and song_ids. Then one GET to /user?ids=<comma_separated_ids> to fetch information about all the users and a GET to song?ids=<comma_separated_ids> to fetch information about all the songs.
  3. GET to /streams and fetch everything in one call. Something like –

    [
    
      {
    
        "user_id" : 10,
        "song_id" : 14,
        "listen_count" : 5,
        "user" : {
          "id"     : 10,
          "name"   : "bla", 
          "email"  : "bla",
        },
        "song" : {
          "id"     : 14,
          "name"   : "blu",
          "album"  : "blu"
       }
      },
    ...
    ]
    

I'm tempted to go with option 3 because it gives me everything in one call, but I don't think it's very rest-full and I fear that it won't be scalable. Option 2 is good but it takes 3 calls which would mean considerable time loading the list. And option 1 follows rest but will take numerous calls for showing the list and doing so many calls from a mobile device isn't feasible.

What would be the recommended way to go about this?

Best Answer

When creating a REST interface, there is no requirement, or even expectation, that the responses on the REST interface correspond directly to tables or joins in the database.

Your /streams interface can just as easily be represented as

[
  {
    "listen_count" : 5,
    "user" : {
      "href"     : "/users/10",
      "name"   : "bla", 
    },
    "song" : {
      "href"     : "/songs/14",
      "name"   : "blu",
      "album"  : "blu"
    }
  },
  ...
]

Where the JSON objects contain the main details of users and songs that are (nearly) always relevant for consumers of a stream resource, and a link to the relevant user/song resources if further details are needed.

This is essentially a variation of your third option, with a fallback to option 1 if more details are needed.

Related Topic