root对象还是没有? API响应的最佳做法是什么?

时间:2013-08-23 20:17:03

标签: android ios json api

JSON响应数据的最佳做法是什么,将对象嵌套在父对象中并包含根密钥路径?

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

似乎大多数HTTP框架(RestKit,GSON等)可以处理任何一种情况,但我希望得到一个明确的答案,哪种方法更好,为什么。我觉得第一种方法更具描述性,总是很好,但第二种方法更轻量级,你已经知道基于url路径映射到哪个对象。

注意:我要求具体参考移动应用后端。

3 个答案:

答案 0 :(得分:3)

当您从外部源(或任何地方)收到对象时,一切皆有可能。您需要检查对象以查看如何以及是否可以使用它。

保持简单。

Twitter的API比Facebook更容易消费,因为当你得到一个结果时,你几乎不必对它进行无效检查。

考虑以下代码:

Twitter的:

if (result.profile_image_url) {
    // use it
}

Vs以上。 Facebook的:

if (result.data && result.data.picture && result.data.picture.url) {
   // use it
}

IMO,更好的解决方案很明确。根对象没有错,但是您的API应该使客户能够简单易用。

答案 1 :(得分:2)

看起来两个方都有牵引力。

赞成根元素

根据JSONAPI.org

  

它的根密钥必须与服务器对集合的GET请求的响应中提供的根密钥相同。

     

例如,假设以下请求收集照片:

GET /photos

HTTP/1.1 200 OK
Content-Type: application/json

{
  "photos": [{
    "id": "1",
    "title": "Mustaches on a Stick"
  }]
}

赞成没有根元素

Twitter在使用设置对象

时不会
{
    "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使用数据和元数据的组合,但不使用root 用户对象

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

答案 2 :(得分:2)

a)描述资源/集合的根密钥

这有利于响应中的额外上下文。根密钥描述资源或集合。我个人喜欢这种方法,因为很明显响应文档描述了什么 - 您可能会认为它从端点显而易见,但情况并非总是如此。

b)没有描述资源/集合的根密钥

这种方法在野外更常见。需要高可用性和快速的API通常会从响应文档中删除不必要的数据,以减少服务器负载和请求大小。这是其他人在设计自己的API时所看到的典型流行API,因此您可以看到它是针对不在相同条件下运行的API进行模拟的。

我不认为缺少根密钥会使响应更容易使用。从嵌套在一层深度的JSON对象获取数据是一项微不足道的工作。

c)根密钥为"data"

发布此问题时,JSON API specification尚未达到v1.0,这意味着可能会发生重大变更。如果您现在查看其(稳定)规范,您会看到their stance on the root key已更改。

The proposal for v1.0 Release Candidate 2 changed the top-level key to "data".

  

主要资源现在必须出现在顶级"data"键下。

以此奇异资源为例

{
  "data": {
    "type": "articles",
    "id": "1",
    "attributes": {
      "title": "The best article of all time",
      "author": "Kanye West"
    }
 }

我找不到这背后的原因,但我怀疑这是因为一致性。无论资源如何,都可以始终从文档响应中获取数据,因为顶级成员是一致的,假设API遵循JSON API v1.0规范。