What is the best practice for JSON response data, nest the object within a parent object and include the root keypath or not?
{
"activity": {
"id": 20,
"description": "a nice walk",
"time_occurred": "2013-07-15T22:10:23Z",
"duration": 45,
"distance": 4.24,
"location":"McDonalds"
}
}
OR
{
"id": 20,
"description": "a nice walk",
"time_occurred": "2013-07-15T22:10:23Z",
"duration": 45,
"distance": 4.24,
"location":"McDonalds"
}
Seems like most HTTP frameworks (RestKit, GSON, etc) can handle either case, but I'd love to have a definitive answer on which approach is better and why. I feel like the first approach is more descriptive, which is always good, but the second approach is more lightweight and you should already know what object to map to based on the url path.
Note: I'm asking with specific reference to mobile app backends.
This has the benefit of extra context in the response. The root key describes the resource or collection. I personally like this approach because it's obvious what the response document is describing -- you may argue that it's obvious from the endpoint, but this isn't always the case.
This approach is more common in the wild. APIs that need to be high availability and fast will often strip out unnecessary data from the response document to reduce server load and request size. This typical of popular APIs that others look at when designing their own, and so you see it emulated for APIs that don't operate under the same conditions.
I don't buy the argument that lack of a root key makes the response easier to work with. It's an insignificant amount of effort to fetch data from a JSON object nested one level deep.
"data"
When this question was posted, the JSON API specification had not yet reached v1.0 which means breaking changes were likely to occur. If you view their (stable) specification now, you'll see that their stance on the root key has changed.
The proposal for v1.0 Release Candidate 2 changed the top-level key to "data"
.
Primary resources MUST now appear under the top-level
"data"
key.
Take for example this singular resource
{
"data": {
"type": "articles",
"id": "1",
"attributes": {
"title": "The best article of all time",
"author": "Kanye West"
}
}
I couldn't find the reason behind this, but I suspect it's because of consistency. No matter the resource, one can always fetch data from the document response because the top-level members are consistent, assuming the API follows the JSON API v1.0 specification.
Looks like both sides have traction.
According to JSONAPI.org
Its root key MUST be the same as the root key provided in the server's response to GET request for the collection.
For example, assuming the following request for the collection of photos:
GET /photos
HTTP/1.1 200 OK
Content-Type: application/json
{
"photos": [{
"id": "1",
"title": "Mustaches on a Stick"
}]
}
Twitter does not when it uses a settings object
{
"always_use_https": true,
"discoverable_by_email": true,
"geo_enabled": true,
"language": "en",
"protected": false,
"screen_name": "theSeanCook",
"show_all_inline_media": false,
"sleep_time": {
"enabled": false,
"end_time": null,
"start_time": null
},
"time_zone": {
"name": "Pacific Time (US & Canada)",
"tzinfo_name": "America/Los_Angeles",
"utc_offset": -28800
},
"trend_location": [
{
"country": "United States",
"countryCode": "US",
"name": "Atlanta",
"parentid": 23424977,
"placeType": {
"code": 7,
"name": "Town"
},
"url": "http://where.yahooapis.com/v1/place/2357024",
"woeid": 2357024
}
],
"use_cookie_personalization": true
}
Instagram uses a combination of data and metadata, but does not use a root user object
{
"meta": {
"code": 200
},
"data": {
"username": "obama",
"bio": "",
"website": "",
"profile_picture": "http://images.ak.instagram.com/profiles/anonymousUser.jpg",
"full_name": "",
"counts": {
"media": 30,
"followed_by": 113,
"follows": 130
},
"id": "2082346"
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With