Реактивный поток с MongoDB, Kotlin и Spring WebFlux

Реактивный поток с MongoDB, Kotlin и Spring WebFlux

1. Overviewс

В этом руководстве мы напишем простое приложение, демонстрирующее полностью реактивный поток с использованием Spring Data Reactive MongoDB и SpringSSeEmitter.

С одной стороны, мы применим Spring Data Reactive MongoDB для сохранения данных через реактивную базу данных Mongo и объединим их с механизмом Server-Sent-Events для уведомления подписанных клиентов о входящих данных.

Кроме того, мы воспользуемся поддержкой Kotlin в Spring Boot.

Итак, начнем!

2. Настроить

Прежде всего, мы должны настроить наш проект Maven, добавив зависимость Spring Data Reactive MongoDB в нашpom.xml:


    org.springframework.boot
    spring-boot-starter-data-mongodb-reactive

Более того, чтобы использовать Kotlin, нам нужно добавитьKotlin standard library в тот же файл:


    org.jetbrains.kotlin
    kotlin-stdlib

Теперь мы готовы приступить к разработке нашего приложения. Мы начнем настраивать среду для поддержки реактивного программирования и Mongo DB, так что вперед!

3. Реактивная конфигурация Mongo

Первое, что нам нужно сделать, это настроить наш проект для поддержки реактивных данных Spring. Мы добавим новый класс, расширяющийAbstractReactiveMongoConfiguration, для настройки реактивного клиента Mongo и репозитория данных Spring:

@Configuration
@EnableReactiveMongoRepositories(
  basePackageClasses = arrayOf(EventRepository::class))
class MongoConfig : AbstractReactiveMongoConfiguration() {

    override fun getDatabaseName() = "mongoDatabase"

    override fun reactiveMongoClient() = mongoClient()

    @Bean
    fun mongoClient() = MongoClients.create()

    @Bean
    override fun reactiveMongoTemplate()
     = ReactiveMongoTemplate(mongoClient(), databaseName)
}

Эта конфигурация не требуется, если мы хотим взаимодействовать с MongoDB без реакции. Обратите внимание, что мы должны добавить тег@EnableReactiveMongoRepositories, чтобы конфигурация знала, где находятся наши репозитории Spring Data. 

После этого мы готовы приступить к реализации основных функций. The first thing we’ll do is develop a new data class to persist the incoming information and then, a related Spring Data reactive repository to manage that persistence.с

4. Документ

document - это единица хранения данных в базе данных MongoDB. Этот модуль использует стиль JSON для хранения данных.

В нашем проекте мы сохраним простоту, используя фиктивныйdocument caledEvent с двумя атрибутами:id иname:.

@Document
class Event(id: String, name: String)

5. Реактивный репозиторий данных Spring

Цель Spring Data абстракции - уменьшить объем кода, необходимый для реализации уровней доступа к данным для постоянных хранилищ.

Следовательно, реактивная версия работает так же, поэтому у нас будет следующая строка для реализации всего реактивного репозитория:

interface EventRepository : ReactiveMongoRepository

6. контроллер

КлассController будет отвечать за отправку Server-Sent Event при сохранении любых реактивных данных.

МетодsaveAndSend сначала сохраняет входящие данные в нашу базу данных Mongo Reactive, делегируя это действие нашемуEventRepository. 

Следовательно, мы добавим новую конечную точку, которая создает и сохраняет новыеEvents.

Во-первых, давайте посмотрим на код Kotlin:

@GetMapping(value = "/save",
  produces = arrayOf(MediaType.TEXT_EVENT_STREAM_VALUE))
fun saveAndSend(@RequestParam("eventName") eventName: String) =
  eventRepository
    .save(Event(UUID.randomUUID().toString(), eventName))
    .flux()

Как мы видим, после сохранения новых данных реактивный репозиторий Spring Data вернет SSE, который будет отправлен подписанному клиенту.

На данный момент, мы можем сказать, что у нас есть полный реактивный проект на стороне сервера Kotlin. У нас уже есть все необходимые элементы для запуска нашего приложения Spring Boot.

Таким образом, теперь мы рассмотрим, как создать простой веб-клиент для отправки и получения всех наших созданных событий Server-Sent.

7. подписчик

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

Посмотрим, как это реализовано:

7.1. Отправить данные

Клиент сохранит набранное имя события с помощью кнопки sSave new event .

Это, в свою очередь, сделает HTTP-запрос к конечной точке нашего сервераsaveEvent:

7.2. Получить данные

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

Однако в нашем примере мы сделаем это как можно проще:

8. Заключение

В заключениеSpring Data MongoDB has been updated to leverage the reactive programming model introduced in Spring Framework 5. Теперь у нас есть простой способ использовать эту парадигму программирования и события Server-Sent.

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

Реализацию этого примера можно проверитьin the GitHub project.

Это проект, основанный на Maven, поэтому запустите приложение Spring Boot, чтобы увидеть, как оно работает. Не забудьте сначала запустить сервер Mongo DB.