Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free.

When it comes to JSON APIs is it good practice to flatten out responses and avoid nested JSON objects?

As an example lets say we have an API similar to IMDb but for video games. There are a couple entities, Game, Platform, ESRBRating, and GamePlatformMap which maps Games and Platforms.

Lets say you request /game/1 which fetches the game with ID 1 and it returns the game object with the platforms and esrbRating nested.

{
  "id": 1,
  "title": "Game A",
  "publisher": "Publisher ABC",
  "developer": "Developer DEF",
  "releaseDate": "2015-01-01",
  "platforms": [
    {"id":1,"name":"Xbox"},
    {"id":2,"name":"Playstation"}
  ],
  "esrbRating": {
    "id": 1,
    "code": "E",
    "name": "Everyone"
  }
}

If you are using something like JPA/Hibernate it may automatically do this for you if it is set to FETCH.EAGER.

The other option is to simply the API and add more end points.

In that case when /game/1 is requested just the game object is returned.

{
  "id": 1,
  "title": "Game A",
  "publisher": "Publisher ABC",
  "developer": "Developer DEF",
  "releaseDate": "2015-01-01",
}

If you want the platforms and/or ESRBRating you would have to call the following:

/game/1/platform /game/1/esrb

This method seems like it could potentially add several more calls to the server depending on what data the client needs and when they need it.

There was one last thought I had where you would have something like this returned.

{
  "id": 1,
  "title": "Game A",
  "publisher": "Publisher ABC",
  "developer": "Developer DEF",
  "releaseDate": "2015-01-01",
  "platforms": ["Xbox","Playstation"]
}

However this assumes they don't need the IDs or whatever other information may be associated with those platform objects.

I asking in general what is the best way to structure your JSON objects returned from your API. Should you try to stay as close to your entities as possible, or is it fine to use Domain Objects or Data Transfer Objects? I understand the methods will have trade offs, either more work on the data access layer or more work for the client.

I would also like to hear an answer related to using Spring MVC as the backend technology for the API, with either JPA/Hibernate or MyBatis for persistence.

share|improve this question
3  
What objections, if any, do you have returning embedded objects? Returning embedded objects individually from different endpoints is going to get pretty damn annoying (not to mention slow). –  Robert Harvey Feb 9 at 0:21
    
Personally I have no objections to it. I'm just not aware of what is considered best practices. A colleague claims working with embedded objects in AngularJS is not straight forward and eventually I would like either Ember of AngularJS app to consume the API. I don't know enough about Angular or Ember to know if that will have an impact or not. –  greyfox Feb 9 at 0:24
3  
The answer is going to depend on whether you wish to return domain objects, DTO's, ViewModel objects, or KitchenSink objects. Which object you're returning is very likely going to be determined by what your application needs, and how said object behaves over the Internet. Example: if you're trying to fill a web page with data from an invoice, very likely you're going to return an object containing everything you need (unless you plan on AJAXing in the line items, or something like that). –  Robert Harvey Feb 9 at 0:26
    
Which is this case when you request a game you would likely want to know the genres, platforms, and ESRBRating. That makes sense. In terms of design from a Java perspective would you recommend having Entity package which has JPA entites, and then a domain package which is the business objects / DTO being return to the user? –  greyfox Feb 9 at 0:30
    
Calls to the server are expensive. An API that requires you to send data using multiple calls will be slower than an API that lets you get everything in one call, often even when the latter returns unneeded information. –  Steven Burnap Feb 9 at 1:21

2 Answers 2

up vote 1 down vote accepted

Another alternative (using HATEOS). This is simple, mostly in practice you add a links tag in the json depending on your use of hateos.

http://api.example.com/games/1:

{
  "id": 1,
  "title": "Game A",
  "publisher": "Publisher ABC",
  "developer": "Developer DEF",
  "releaseDate": "2015-01-01",
  "platforms": [
    {"_self": "http://api.example.com/games/1/platforms/53", "name": "Playstation"},
    {"_self": "http://api.example.com/games/1/platforms/34", "name": "Xbox"},
  ]
}

http://api.example.com/games/1/platforms/34:

{
  "id": 34,
  "title": "Xbox",
  "publisher": "Microsoft",
  "releaseDate": "2015-01-01",
  "testReport": "http://api.example.com/games/1/platforms/34/reports/84848.pdf",
  "forms": [
    {"type": "edit", "fields: [] },
  ]
}

You can off course embed all data in all listing but that will likely be way too much data. This way you can embed the required data and then load more if you really want to work with it.

The technical implementation can contain caching. You can cache the platforms links and names in the game object and send it instantly without having to load the platforms api at all. Then when required you can load it.

You see for example that I added some form information. I did that to show you there can be much more information in a detailed json object than you would even want to load in the listing of games.

share|improve this answer
    
I don't think that's technically HATEOS since there is no state. –  RibaldEddie Feb 9 at 7:14
    
Yeah, not sure the exact word on this process. HATEOS in general is being used for linking in rest API's but I agree it also has to do with state. Though the idea of implementation will be the same. Here you see a bit more about how it can be used by an example: stormpath.com/blog/linking-and-resource-expansion-rest-api-tips –  Luc Franken Feb 9 at 13:35
    
It's a good idea though! –  RibaldEddie Feb 18 at 17:08

This is one of those basic questions when it comes to REST API design. Every designer asks themselves this question on the first day. Sorry but the answer is "it depends". Each approach has pros and cons and you'll just need to make a decision and go with it.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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