Using reactive drivers (MongoDB)

Reactive MongoDB connectivity in Spring Data is built on MongoDB Reactive Streams Java Driver (https://github.com/mongodb/mongo-java-driver-reactivestreams). The driver provides asynchronous stream processing with non-blocking backpressure. In turn, the reactive driver is built on top of MongoDB Async Java Driver (http://mongodb.github.io/mongo-java-driver/3.8/driver-async). The asynchronous driver is low level and has a callback-based API, so it is not as easy to use as the more high-level Reactive Streams driver. We have to note that along with the MongoDB Reactive Streams Java Driver there is also MongoDB RxJava Driver (http://mongodb.github.io/mongo-java-driver-rx), which is also built on top of the same asynchronous MongoDB driver. So, for MongoDB connectivity, the Java ecosystem has one synchronous, one asynchronous, and two reactive drivers.

Of course, if we need more control over the query process than ReactiveMongoTemplate gives us, we may use the reactive driver directly. With that approach, the previous example with the pure reactive driver is as follows:

public class RxMongoDriverQueryService {
   private final MongoClient mongoClient;                          // (1)

   public Flux<Book> findBooksByTitleRegex(String regex) {         // (2)
      return Flux.defer(() -> {                                    // (3)
         Bson query = Filters.regex(titleRegex);                   // (3.1)
         return mongoClient                                        //
              .getDatabase("test-database")                        // (3.2)
              .getCollection("book")                               // (3.3)
              .find(query);                                        // (3.4)
      })
         .map(doc -> new Book(                                     // (4)
            doc.getObjectId("id"),
            doc.getString("title"),
            doc.getInteger("pubYear"),
            // ... other mapping routine
         ));
   }
}

Let's look at the preceding code:

  1. The service refers to the instance of the com.mongodb.reactivestreams.client.MongoClient interface. This instance should be accessible as a Spring bean when the data source is configured correctly.
  2. The service defines the findBooksByTitleRegex method, which returns a Flux with Book entities.
  3. We have to return a new Flux instance, which defers the execution until the time when the actual subscription happens. Inside that lambda, we define a new query with the org.bson.conversions.Bson type using the com.mongodb.client.model.Filters helper class. Then we reference the database (3.2) as well as the collection (3.3) by names. No communication with the database happens unless we send the previously prepared query (3.4) with the find method.
  4. As soon as results start coming back, we may transfer MongoDB documents into domain entities, if that is required at all.

Even though in the preceding example we work at the database driver level, it is still pretty comfortable as we operate with Reactive Streams. Besides, we do not need to handle backpressure manually as the MongoDB Reactive Streams Java Driver already supports it. Reactive MongoDB connectivity uses backpressure demand based on batch size. This approach is a sane default but can generate many roundtrips when using small demand increments. The following diagram highlights all the abstraction layers required for a reactive MongoDB repository:

Diagram 7.16 Reactive MongoDB stack with Spring Data
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.187.113