Giriş
Açıklaması şöyle
Örnek
Şöyle yaparız. Burada RestController Mono<...> veya Flux<...> tipleri dönüyor. çünkü service nesnesi Mono ve Flux döndürüyor.
Örnek
Açıklaması şöyle
As Spring 5.x comes with Reactor implementation, if we want to build REST APIs using imperative style programming with Spring servlet stack, it still supports.
Örnek - FluxSink ile Kendi Flux Sınıfımız
Elimizde şöyle bir controller olsun. Bir tane Flux nesnesi Course nesnesini çektikçe bunu CourseDto olarak gönderiyor.
import dev.bluvolve.reactive.courseservice.course.mappers.CourseMapper;import dev.bluvolve.reactive.courseservice.course.processors.CourseCreatedEventProcessor;import reactor.core.publisher.Flux;@RestControllerpublic class CourseController {private final CourseMapper mapper;private final Flux<CourseCreated> events;public CourseController(CourseCreatedEventProcessor processor,CourseMapper mapper) {this.mapper = mapper;this.events = Flux.create(processor).share();}@GetMapping(value = "/course/sse", produces = "text/event-stream;charset=UTF-8")public Flux<CourseDto> stream() {return this.events.map(event -> {CourseDto dto = this.mapper.entityToDto((Course) event.getSource());return dto;});}...}
Flux.create() metodunun imzası şöyle. Yani bir tane FluxSink'ten kalıtan java.util.function.Consumer istiyor.
Flux.create(Consumer<? super FluxSink<T>> emitter)
Consumer şöyledir. Kendisine CourseCreated SpringEvent'i geldikçe bunu kuyruğa yazar. Kuyruğu boşaltan thread ise FluxSink.next(event) çağrısı ile sink'e yazar. Sink'i dinleyen controller ise CourseCreatedEvent nesnesini mapper vasıtasıyla CourseDto nesnesine çevirir ve gönderir.
import dev.bluvolve.reactive.courseservice.course.events.CourseCreated;import reactor.core.publisher.FluxSink;import java.util.function.Consumer;@Componentpublic class CourseCreatedEventProcessorimplements ApplicationListener<CourseCreated>,Consumer<FluxSink<CourseCreated>> {private final Executor executor;private final BlockingQueue<CourseCreated> queue = new LinkedBlockingQueue<>();CourseCreatedEventProcessor(Executor executor) {this.executor = executor;}@Overridepublic void onApplicationEvent(CourseCreated event) {this.queue.offer(event);}@Overridepublic void accept(FluxSink<CourseCreated> sink) {this.executor.execute(() -> {while (true)try {CourseCreated event = queue.take();sink.next(event);}catch (InterruptedException e) {...}});}}
Şöyle yaparız. Burada RestController Mono<...> veya Flux<...> tipleri dönüyor. çünkü service nesnesi Mono ve Flux döndürüyor.
@RestController
public class ProductController {
@Autowired
private ProductService productService;
//This endpoint allows to create a product.
@PostMapping("/product")
@ResponseStatus(HttpStatus.CREATED)
public Mono<Product> createProduct(@RequestBody Product product){
return productService.save(product);
}
//This endpoint gives all the products
@GetMapping("/products")
public Flux<Product> getAllProducts(){
return productService.getAllProducts();
}
//This endpoint allows to delete a product
@DeleteMapping("/product/{id}")
public Mono<Void> deleteProduct(@PathVariable int id){
return productService.deleteProduct(id);
}
//This endpoint allows to update a product
@PutMapping("product/{id}")
public Mono<ResponseEntity<Product>> updateProduct(@RequestBody Product product){
return productService.update(product);
}
}
Örnek
Burada POST edilen parametreyi de Mono tipine çeviriyoruz
@PostMapping(path = "", produces = MediaType.APPLICATION_JSON_UTF8_VALUE,consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)public Mono<Reservation> createReservation(@RequestBody Mono<Reservation>
reservationRequest) {return reservationService.createReservation(reservationRequest);}
Şöyle yaparız. Burada Repository Mono tipi döndürmüyor. Mono.just().xxx() şeklin de kendimiz kodluyoruz
@RestController@RequestMapping(value = "/posts")class PostController {private final PostRepository posts;@GetMapping("/{id}")public Mono<Post> get(@PathVariable("id") Long id) {return Mono.just(id).flatMap(posts::findById).switchIfEmpty(Mono.error(new PostNotFoundException(id)));}@PutMapping("/{id}")public Mono<Post> update(@PathVariable("id") Long id, @RequestBody Post post) {return this.posts.findById(id).map(p -> {p.setTitle(post.getTitle());p.setContent(post.getContent());return p;}).flatMap(this.posts::save);}}
Hiç yorum yok:
Yorum Gönder