Как правильно использовать HAL (Hypermedia Application Language) _embedded?

Я создаю REST API, который предоставляет пользователям информацию об онлайн-курсах. Вот общая структура курса:

Курс> Единицы> Уроки> Мероприятия

Я пытаюсь сделать мою структуру ответов JSON HAL-совместимой, но я не уверен, правильно ли я это делаю.

Что из следующего является правильным:

{
  “kind”: “clms#course”,
  “id”: long,
  “course-name”: string,
  “course-icon”: string,
  “product-name”: string,
  “product-icon”: string,
  “_links”: {
    “self”: {“href” : string}, 
    “unitlist”: {“href” : string} // This is a link to list of units for the course.
  }
}

Или ссылка на список единиц является встроенным ресурсом?

{
      “kind”: “clms#course”,
      “id”: long,
      “course-name”: string,
      “course-icon”: string,
      “product-name”: string,
      “product-icon”: string,
      “_links”: {
        “self”: {“href” : string}, 
      }
      "_embedded": {
        “unitlist”: {“href” : string} // This is a link to list of units for the course.
      }
    }

Или оба не правы? Любая помощь приветствуется.

Ура, Олли

1 ответ

Решение

Мало вещей. Позвольте мне провести вас через этот процесс, и это может помочь.

Начните только с ссылок и их отношений. Есть курс, есть единицы. Таким образом, каждая единица относится к курсу как к единице. используйте это как ваше имя отношения. так:

{
  “kind”: “clms#course”,
  “id”: long,
  “course-name”: string,
  “course-icon”: string,
  “product-name”: string,
  “product-icon”: string,
  “_links”: {
    “self”: {“href” : string}, 
    “unit”: [
       {“href” : url-of-first-unit},
       {“href” : url-of-second-unit},
       {“href” : url-of-third-unit},
       ...
    ]
  }
}

но unit не является зарегистрированной связью IANA, поэтому на самом деле это должен быть URI или карри к URI:

“_links”: {
    “self”: {“href” : string},
    "curies" : [
       {"href" : "http://youndomain/rels/{rel}", name : "x" }
    ],
    “x:unit”: [
       {“href” : url-of-first-unit},
       {“href” : url-of-second-unit},
       {“href” : url-of-third-unit},
       ...
    ]
  }

это немного сбивает с толку, но это делает его таким, что ваше устройство "пространственно распределено по именам", и это его собственная вещь, которая хороша.

Теперь поймите, что поиск всех этих юнитов по отдельности был бы болезненным. Я предполагаю, что в вашем пользовательском интерфейсе вы хотите отображать единицы измерения вместе с курсами, поэтому HAL позволяет вам встраивать эти отношения:

{
  “kind”: “clms#course”,
  “id”: long,
  “course-name”: string,
  “course-icon”: string,
  “product-name”: string,
  “product-icon”: string,
  “_links”: {
    “self”: {“href” : string}, 
    "curies" : [
       {"href" : "http://youndomain/rels/{rel}", name : "x" }
    ],
    “x:unit”: [
       {“href” : url-of-first-unit},
       {“href” : url-of-second-unit},
       {“href” : url-of-third-unit},
       ...
    ]
  },
  "_embedded" : {
    “x:unit”: [
       { some json representing the unit located at url-of-first-unit},
       { some json representing the unit located at url-of-second-unit},
       { some json representing the unit located at url-of-third-unit},
       ...
    ]
  }
}

Теперь клиент может встроить мой блок проверки вместо проверки ссылок. На самом деле, поскольку он встроен, на самом деле нет никакой причины включать ссылки (если вы не знаете, что клиент зависит от них):

{
  “kind”: “clms#course”,
  “id”: long,
  “course-name”: string,
  “course-icon”: string,
  “product-name”: string,
  “product-icon”: string,
  “_links”: {
    “self”: {“href” : string}, 
    "curies" : [
       {"href" : "http://youndomain/rels/{rel}", name : "x" }
    ],
  },
  "_embedded" : {
    “x:unit”: [
       { some json representing the unit located at url-of-first-unit},
       { some json representing the unit located at url-of-second-unit},
       { some json representing the unit located at url-of-third-unit},
       ...
    ]
  }
}

Так что теперь клиент имеет их в качестве встроенного ресурса и не нуждается в извлечении ресурсов с помощью http-запросов.

В целом, я бы предложил начать со ссылок на все, и оптимизировать для ваших случаев использования встроенными ресурсами.

Несколько дополнительных заметок:

  • Если вам действительно нужно собрать все единицы вместе в одном ресурсе, возможно, рассмотрите это как страницу со встроенными элементами, которые будут единицами. Отношение от курса к странице юнитов [s], вероятно, было бы x: единиц.
  • Избегайте использования поля id на вашем ресурсе, если id не является чем-то, что известно внешнему миру. Самостоятельная ссылка - это гораздо лучший внешний идентификатор, так как это URL, и его легче превратить в реальный ресурс.
  • Я предпочитаю ссылки в профиле, а не на "доброе" поле, особенно когда оно выглядит как enum. проверить https://tools.ietf.org/html/rfc6906
Другие вопросы по тегам