RESTful способ справиться с двунаправленными отношениями между ресурсами - PullRequest
8 голосов
/ 08 февраля 2012

Давайте предположим, что я хотел разработать REST API, в котором говорится о песнях, альбомах и исполнителях (на самом деле я делаю, как 1312414 человек до меня).

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

Таким образом, представления будут выглядеть примерно так:

{
   song: 'xyz',
   links: [
      { rel: 'album', url: '.../albums/abc' }
   ]
}

{
   album: 'abc',
   links: [
      { rel: 'song', url: '.../songs/xyz' },
      { rel: 'song', url: '...' },
      { rel: 'song', url: '...' },
      { rel: 'song', url: '...' }
   ]
}

Учитывая, что я хочу, чтобы это было справедливо (возможно, проблема заключается в «Данные»), как я могу спроектировать свой API так, чтобы создание ресурса альбома или песни не имело побочных эффектов для ранее существующих ресурсы песни или альбома?

Это какая-то проблема курицы / яйца. Если я сначала создаю ресурс песни (POST / songs /), а затем создаю ресурс альбома (POST / album /), ресурс песни модифицируется как часть создания альбома (что плохо в соответствии с принципами REST) ​​из-за ассоциации между двумя ресурсами обновляется на сервере. Аналогично сценарию, где я сначала создаю альбом, а затем песню.

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

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

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

1 Ответ

1 голос
/ 06 ноября 2012

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

Таким образом, в вашем случае нет ничего изначально некорректного в том, что ресурс Song может эффективно добавить себя к ресурсу Album. Также нет ничего неправильного в том, что ресурс Album может сказать, что ресурс Song является его частью.

Теперь, учитывая ваши бизнес-требования, вы можете либо: а) изменить способ представления песен / альбомов, либо б.) Разрешить привязку песен / альбомов в м / м стиле вместо 1/1. Причина этого заключается в том, что в зависимости от того, как вы структурируете свои данные и выбираете ресурсы (то есть адресуемые блоки) в вашей системе, вы фактически моделируете различные взаимосвязи данных, и это, я думаю, суть проблемы, с которой вы сталкиваетесь .

С Songs и Albums отдельными ресурсами в вашей системе, для обеспечения более строгих отношений, таких как 1/1 вместо м / м, требуется гораздо больше работы и спецификаций для типов вашего контента. Вы должны разобраться со случаями, когда два разных альбома считают, что они содержат одну песню, но отношение 1/1 не позволяет этого.

Если у вас есть объект Album, явно содержащий или собственный Song объектов, тогда проблема меньше, так как Album может манипулировать только своим собственным песни, а не таковые из любых других Album. Однако изменяет модель данных, поскольку Songs уже не являются гражданами первого класса, а вместо этого под альбомом, которому они принадлежат.

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

Нет ничего плохого в том, что обе стороны (Album и Song) владеют им. Это прекрасно работает для отношения м / м, но для отношения 1/1, которое требует либо гораздо больших накладных расходов на управление (т. Е. Что-то еще действительно владеет отношением).

Если вы хотите, чтобы отношение 1/1 без всех накладных расходов, однако, вы должны иметь один участвующих субъектов, владеющих отношением, что означает, что существует только один путь изменить его ... через собственника.

...