Skip to content

13.1.2 Định nghĩa các repository phản ứng

Trong chương 3 và 4, chúng ta đã định nghĩa các repository dưới dạng các interface mở rộng từ interface CrudRepository của Spring Data. Nhưng interface repository cơ bản đó chỉ xử lý các đối tượng đơn lẻ và các tập hợp Iterable. Ngược lại, chúng ta kỳ vọng một repository phản ứng sẽ xử lý các đối tượng MonoFlux.

Đó là lý do tại sao Spring Data cung cấp ReactiveCrudRepository để định nghĩa các repository phản ứng. ReactiveCrudRepository hoạt động tương tự như CrudRepository. Để tạo một repository, hãy định nghĩa một interface mở rộng ReactiveCrudRepository, ví dụ như sau:

java
package tacos.data;

import org.springframework.data.repository.reactive.ReactiveCrudRepository;

import tacos.TacoOrder;

public interface OrderRepository
      extends ReactiveCrudRepository<TacoOrder, Long> {
}

Ở bề ngoài, điểm khác biệt duy nhất giữa OrderRepository này và những cái mà chúng ta đã định nghĩa ở chương 3 và 4 là nó mở rộng ReactiveCrudRepository thay vì CrudRepository. Nhưng điểm khác biệt quan trọng là các phương thức của nó trả về kiểu MonoFlux thay vì một đối tượng TacoOrder đơn lẻ hoặc Iterable<TacoOrder>. Hai ví dụ bao gồm phương thức findById(), trả về Mono<TacoOrder>, và findAll(), trả về Flux<TacoOrder>.

Để thấy repository phản ứng này hoạt động như thế nào, giả sử bạn muốn lấy tất cả các đối tượng TacoOrder và in tên người nhận hàng ra chuẩn đầu ra. Trong trường hợp đó, bạn có thể viết đoạn mã như sau.

Danh sách 13.4 Gọi phương thức từ repository phản ứng

java
@Autowired
OrderRepository orderRepo;

...

orderRepository.findAll()
  .doOnNext(order -> {
    System.out.println(
      "Deliver to: " + order.getDeliveryName());
    })
  .subscribe();

Ở đây, lời gọi đến findAll() trả về một Flux<TacoOrder> mà chúng ta đã thêm một doOnNext() để in ra tên người nhận hàng. Cuối cùng, lời gọi subscribe() sẽ khởi động luồng dữ liệu chảy qua Flux.

Trong ví dụ Spring Data JDBC ở chương 3, TacoOrder là root của aggregate, với Taco là thành phần con trong aggregate đó. Do đó, các đối tượng Taco được lưu trữ như một phần của TacoOrder, và không cần định nghĩa repository riêng để lưu Taco. Nhưng Spring Data R2DBC không hỗ trợ aggregate root một cách đầy đủ như vậy, nên chúng ta sẽ cần một TacoRepository để lưu trữ các đối tượng Taco. Xem danh sách sau để biết một repository như vậy.

Danh sách 13.5 Lưu trữ các đối tượng Taco với repository phản ứng

java
package tacos.data;

import org.springframework.data.repository.reactive.ReactiveCrudRepository;
import tacos.Taco;

public interface TacoRepository
      extends ReactiveCrudRepository<Taco, Long> {
}

Như bạn thấy, TacoRepository không khác nhiều so với OrderRepository. Nó mở rộng ReactiveCrudRepository để cung cấp các kiểu phản ứng khi làm việc với lưu trữ Taco. Không có điều gì bất ngờ ở đây.

Mặt khác, IngredientRepository thú vị hơn một chút, như thể hiện dưới đây.

Danh sách 13.6 Lưu trữ các đối tượng Ingredient với repository phản ứng

java
package tacos.data;

import org.springframework.data.repository.reactive.ReactiveCrudRepository;

import reactor.core.publisher.Mono;
import tacos.Ingredient;

public interface IngredientRepository
      extends ReactiveCrudRepository<Ingredient, Long> {

  Mono<Ingredient> findBySlug(String slug);

}

Cũng như các repository phản ứng khác, IngredientRepository mở rộng ReactiveCrudRepository. Nhưng vì chúng ta có thể cần một cách để tìm các đối tượng Ingredient dựa trên giá trị slug, IngredientRepository bao gồm một phương thức findBySlug() trả về Mono<Ingredient>.

Giờ hãy xem cách viết test để kiểm tra rằng các repository của chúng ta hoạt động chính xác.

Released under the MIT License.