androidiosjsonapi-design

Root object or no? What is the best practice for API responses?


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.


Solution

  • Looks like both sides have traction.

    In Favor of root elements

    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"
      }]
    }
    

    In favor of no root element

    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"
      }
    }