Как установить отношения между службами Spring Data REST/Spring HATEOAS (микро)?

Попытка выяснить шаблон того, как обрабатывать отношения при использовании микросервисов на основе гипермедиа на основе Spring Data Rest или HATEOAS.

Если у вас есть служба A (инструктор) и служба B (курс), каждая из них существует как отдельное приложение.

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

Возможное решение (не уверен, что это правильный путь)

У каждой службы есть вторая таблица с OneToMany с основной сущностью в службе. В таблице будут следующие поля:

ID, entityID, rel, relatedID

Затем в противоположном сервисе с использованием Spring Data Rest настраивается поиск, который запрашивает таблицу соединений, чтобы найти совпадающие записи.

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


person code    schedule 06.01.2015    source источник
comment
Я думаю, что будет некоторая зависимость от каждого, как только у вас будут разные версии каждого API. Тем не менее, неплохая идея подключить API, сохранив их ссылки и используя SDR для создания ссылок, указывающих на другой API, используя эти идентификаторы ссылок.   -  person Stackee007    schedule 06.01.2015
comment
@Stackee007 Stackee007 Возможно, я думаю об этом неправильно, я не намерен действительно нуждаться в версиях API. Поскольку по своей сути это HATEOAS, клиент узнает, что ему нужно, при любом изменении. В пределах разумного конечно. Что касается комментария о сохранении ссылки. Вы считаете, что это нормально иметь вторую таблицу для сохранения rel?   -  person code    schedule 07.01.2015


Ответы (2)


Основные шаги следующие:

  1. Службе необходимо обнаружить ресурсы другой службы.
  2. Затем служба добавляет ссылку на ресурсы, которые она отображает, где это необходимо.

У меня есть очень элементарный пример этих шагов в этом репозитории. Пример состоит из двух сервисов: сервис для геопространственного поиска магазинов. Второй сервис — это элементарное управление клиентами, которое при необходимости интегрируется с сервисом магазина, если оно доступно в настоящее время.

Вот как реализованы шаги:

Обнаружение ресурсов

В моем примере служба-потребитель (то есть клиентская) использует API Spring HATEOAS Traverson для обхода набора отношений ссылок, пока не найдет ссылку с именем by-location. Это делается в Интеграция магазина. Таким образом, все, что нужно знать клиентской службе, — это корневой URI (в моем случае взятый из среды) и набор отношений ссылок. Он периодически проверяет существование ссылки с помощью HEAD-запроса.

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

Для еще более сложного подхода взгляните на библиотеку Netflix Eureka, которая по сути представляет собой реестр служб. Кроме того, вы можете проверить нашу интеграцию Spring Cloud для этого.

Пополнение ресурсов ссылками

Spring HATEOAS предоставляет ResourceProcessor API, который использует Spring Data REST. Это позволяет вам манипулировать экземпляром Resource, который должен быть отрендерен, и, например. добавьте на него ссылки. Реализацию для службы клиентов можно найти здесь.

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

За гранью этого

Вы можете найти более сложный вариант этого примера в примерах проектов для Spring Cloud. Он использует тот же пример, но переключается на компоненты Spring Cloud, такие как интеграция Eureka, сбор метрик, добавление пользовательского интерфейса и т. д.

person Oliver Drotbohm    schedule 07.01.2015
comment
P.S. Образец в конце также заменяет периодическую проверку соединения автоматическим выключателем Hystrix. - person Dave Syer; 07.01.2015
comment
Я в основном работаю над примером магазина. Проблема в примере с клиентом/магазином. Связанные магазины поставляются Google через Google API. - person code; 07.01.2015
comment
@Oliver Я согласен (в некоторой степени - даже после привязки другой службы может выйти из строя) с обнаружением другой службы. Однако, если нам нужно связать с определенным ресурсом другой службы, ему нужно сохранить идентификатор ссылки, а затем использовать ResourceProcessor для создания ссылки на другой ресурс, как это делает CustomerResourceProcessor. Теперь возникает вопрос: если есть несколько версий другого сервиса (например, магазинов), как решить, какую версию связать? - person Stackee007; 08.01.2015

В моем случае я могу получить связанные элементы только из самой службы. Моя цель состоит в том, чтобы абстрагировать связанные элементы до такой степени, что любое количество служб может быть связано с службой, и нужно только искать идентификаторы или ссылки. Одной из мыслей было имя @ElementCollection, связанное с объединением идентификатора сущности службы. Затем в @Embedded есть поле relLink и поле relatedID. Затем в репозитории выполните findby, чтобы найти relLink и relatedID.

Надежда состоит в том, чтобы сохранить его достаточно абстрактным, чтобы по существу имитировать настройку «многие ко многим».

person code    schedule 07.01.2015