API версионирования сущностей с детьми - PullRequest
0 голосов
/ 05 октября 2018

Я перевожу некоторые конечные точки API в более сжатую форму.Но у меня возникают некоторые проблемы с обработкой вложенных объектов.

Например:

У меня есть объект Foo и Bar.

Foo v1.0

{
  "field_one": "String",
  "field_two": "String"
}

Foo v1.1

{
  "field_one": "String",
  "field_two": "String",
  "field_three": "String"
}

Bar v1.0

{
  "foo": "Foo",
  "field_one": "String",
  "field_two": "String"
}

Для конечной точки, чтобы получить Foo версия довольно проста, это v1.0 или v1.1, но как мне обработать конечную точку для Bar?Каждое изменение ребенка должно «генерировать» новую версию для родителя?Как поступить, если у родителя более одного версионного ребенка?Если у Bar есть другой дочерний элемент Baz с двумя разными версиями, управление версиями Bar будет продолжаться с итерациями дочерних элементов?

Bar v1.0 -> Foo v1.0
Bar v1.1 -> Foo v1.1
Bar v2.0 -> Foo v1.1 + Baz v1.0

Как сделать это так, если потребительхотите использовать Foo v1.1 для всего своего приложения, он знает, какую версию Bar он должен получить?Просто документация или есть какая-то закономерность?

1 Ответ

0 голосов
/ 26 октября 2018

Все комментарии имеют хорошие отзывы о возможных решениях.Вопрос, который вам нужно задать, заключается в том, содержит ли ваш вложенный ресурс . Сдерживание не позволяет обращаться к ресурсу и, таким образом, его версия соответствует его родительскому элементу.Например, рассмотрим Заказ и связанные с ним Позиции .Элемент строки обычно не должен быть адресуемым сам по себе.

Если у вас есть связанные, но разные, адресуемые ресурсы, любой один ресурс должен не напрямую предоставлять связанный ресурс.Это вводит связь.Способ решить эту проблему в REST - использовать HATEOAS.Есть много способов достижения HATEOAS и только несколько стандартов, которые дают какие-либо рекомендации.Нет правильного ответа на как реализовать HATEOAS, но может выглядеть примерно так:

Bar v1.1

{
  "field_one": "String",
  "field_two": "String",
  "links": [
    { "name": "Foo", "href": "http://localhost/foo/123" }
  ]
}

Это позволяет Bar связываться с Foo без жесткой зависимости от него.Это так же, как веб-сайты создаются с использованием гиперссылок на связанные страницы.

Вот еще несколько замечаний, которые следует учитывать при реализации HATEOAS:

  • В соответствии с UniformОграничение интерфейса , URL является идентификатором (а не 123, как может предположить человек)
  • Вы должны использовать URL-адреса абсолютных ссылок, потому что связанный ресурс может неодин и тот же хост и клиент не должны это выяснять.
  • Хотя это часто встречается, управление версиями по сегментам URL вызывает здесь проблему, потому что как сервер знает, как генерировать ссылки с соответствующимВерсия API?Другие методы, такие как тип носителя, строка запроса или даже заголовок, не страдают от этого.В конечном счете, клиент несет ответственность за , зная , какую версию API запрашивать.У сервера нет возможности узнать, чего хочет клиент.Если сервер не гарантирует симметрию версий, вполне возможно, что клиенты будут связаны с несовместимыми версиями API (например, Foo 1.0 и Bar 1.1).Обеспечение симметрии версий может быть трудным или медленным, если все API должны иметь одинаковые поддерживаемые версии, даже если нет изменений.Я также видел URL templates , используемый для решения проблемы сегмента URL, но, опять же, клиенту не нужно знать или понимать синтаксис шаблона.

Может этобыть полезным в качестве отправной точки для ваших проектов.

...