14

JSON响应数据的最佳实践是什么,将对象嵌套在父对象中并包含根键路径?

{
    "activity": {
        "id": 20,
        "description": "a nice walk",
        "time_occurred": "2013-07-15T22:10:23Z",
        "duration": 45,
        "distance": 4.24,
        "location":"McDonalds"
    }
}

或者

{
    "id": 20,
    "description": "a nice walk",
    "time_occurred": "2013-07-15T22:10:23Z",
    "duration": 45,
    "distance": 4.24,
    "location":"McDonalds"
}

似乎大多数 HTTP 框架(RestKit、GSON 等)都可以处理这两种情况,但我很想对哪种方法更好以及为什么有一个明确的答案。我觉得第一种方法更具描述性,这总是好的,但第二种方法更轻量级,您应该已经知道要根据 url 路径映射到哪个对象。

注意:我问的是移动应用后端的具体参考。

4

3 回答 3

6

a) 描述资源/集合的根键

这有利于响应中的额外上下文。根键描述资源或集合。我个人喜欢这种方法,因为响应文档所描述的内容很明显——您可能会争辩说,从端点来看它是显而易见的,但情况并非总是如此。

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

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

我不相信缺少根密钥会使响应更易于使用的论点。从嵌套一层深的 JSON 对象中获取数据的工作量微不足道。

c) 根密钥是"data"

发布此问题时,JSON API 规范尚未达到 v1.0,这意味着可能会发生重大更改。如果您现在查看他们的(稳定的)规范,您会发现他们对根键的立场已经改变。

v1.0 Release Candidate 2 的提案将顶级密钥更改为"data".

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

以这个单一资源为例

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

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

于 2016-04-10T17:51:05.447 回答
4

看来双方都有牵绊。

有利于根元素

根据 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 使用数据和元数据的组合,但不使用根用户对象

{
  "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"
  }
}
于 2013-08-23T20:35:10.910 回答
3

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

把事情简单化。

Twitter 的 API 比 Facebook 的 API 更易于使用,因为当您获得结果时,您几乎不必对它进行空值检查。

考虑这段代码:

推特:

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

比。Facebook:

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

IMO,更好的解决方案很清楚。根对象没有任何问题,但您的 API 应该让客户端使用起来简单易行。

于 2013-08-30T01:22:07.970 回答