Корневой объект или нет? Какова наилучшая практика для ответов API?

какова наилучшая практика для данных ответа 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-пути.

примечание: Я спрашиваю с конкретной ссылкой на мобильные приложения.

3 ответов


выглядит так:и стороны тяги.

в пользу корневых элементов

По данным JSONAPI.org

его корневой ключ должен совпадать с корневым ключом, предоставленным в ответе сервера для получения запроса на коллекцию.

например, предполагая следующий запрос на сбор фотографий:

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

когда вы получаете объект из внешнего источника (или нигде), все возможно. Вам нужно проверить объект, чтобы увидеть, как и если вы можете использовать его.

сохранить его простым.

API Twitter проще использовать, чем 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 должен сделать его простым и легким для клиентов.


A) корневой ключ, описывающий ресурс / коллекцию

это имеет преимущество дополнительного контекста в ответ. Корневой ключ описывает ресурс или коллекцию. Мне лично нравится этот подход, потому что это очевидно что документ ответа описывает -- вы можете утверждать, что это очевидно из конечной точки, но это не всегда так.

b) нет корневого ключа, описывающего ресурс / коллекцию

этот подход более распространен в дикой природе. API, которые должны быть высокой доступности и быстро, часто удаляют ненужные данные из документа ответа, чтобы уменьшить нагрузку на сервер и размер запроса. Это типично для популярных API, которые другие рассматривают при разработке своих собственных, и поэтому вы видите, что они эмулируются для API, которые не работают в тех же условиях.

Я не покупаю аргумент, что отсутствие корневого ключа упрощает работу с ответом. Это незначительное количество усилий для извлечения данных из JSON объект вложен на один уровень глубже.

c) корневой ключ "data"

когда этот вопрос был опубликован, то спецификация API JSON еще не достиг 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 спецификация.