RxJava and Spring Boot

Author: Shazin Sadakath


It has been a really long time (more than six months) since I wrote my last blog post. Life was a bit busy with coming down from Malaysia and finding a new job in Sri Lanka and settling down. It doesn't mean I was not working with new technologies. Got the chance to work with alot of new technologies and frameworks.

 

Ok having said that while going through the usual weekly dose of InfoQ videos I was bumped on Simon Baslé and Laurent Doguin's talk on Introducing RxJava into a Spring Boot REST API. 

 

I have blogged about Reactive programming previously in this post. Which is all about writing non blocking, concurrent, functional code. Two main aspects of Reactive manifesto is;

  1. Reactive Streams (Observable in RxJava)
  2. Reactive Extensions (Observer/Subscriber in RxJava)


But this time I wanted to go beyond and learn the cores of Reactive Programming. I build a small application which has a Service which returns an Observable (Non blocking) which can be used to asynchronously perform many tasks such filter, zip, map etc.

 

@Component
public class UserService {
 
 public Observable findAll() {
  return Observable.from(new User[] {new User("Shazin", 29), new User("Shahim", 29)});
 }
 
 public Observable findByName(String name) {
  return findAll().filter(u -> u.getName().toLowerCase().contains(name.toLowerCase()));
 }
 
}



This Service can be used in many ways to produces many results as we need and I have used findAll() method in findByName() method to filter records which are only matching the given name. Likewise this gives many more options.

And in the Controller this Service can be used to retrieve the data we want and finally collect those as a List or any other way and pass it back.

@RestController
@RequestMapping("/user")
public class UserController {

 @Autowired
 private UserService userService;

 @RequestMapping(method = RequestMethod.GET) 
 public Observable> find() {
  return userService.findAll().toList();
 }
 
 @RequestMapping(value="/name/{name}", method = RequestMethod.GET)
 public Observable> findByName(@PathVariable String name) {
  return userService.findByName(name).toList();
 }
}



Spring a return type named DeferredResult which will send a response asynchronously when it is finished processing. Either by returning a DeferredResult from the controller method or by writing a custom ReturnValueHandler for Observable we can send asynchronous results.
 

public class ObservableReturnValueHandler implements HandlerMethodReturnValueHandler {

 public boolean supportsReturnType(MethodParameter returnType) {
  Class parameterType = returnType.getParameterType();
  return Observable.class.isAssignableFrom(parameterType);
 }

 public void handleReturnValue(Object returnValue,
   MethodParameter returnType, ModelAndViewContainer mavContainer,
   NativeWebRequest webRequest) throws Exception {
  if(returnValue == null) {
   mavContainer.setRequestHandled(true);
   return;
  }
  
  final DeferredResult deferredResult = new DeferredResult();
  Observable observable = (Observable) returnValue;
  observable.subscribe(result -> deferredResult.setResult(result), errors -> deferredResult.setErrorResult(errors));
  
  WebAsyncUtils.getAsyncManager(webRequest).startDeferredResultProcessing(deferredResult, mavContainer);
  
 }
}

The complete source code can be found at https://github.com/shazin/reactiveapp and I strongly advice to go through the presentation in the references section.
 

References

 

  1. Introducing RxJava into a Spring Boot REST API - http://www.infoq.com/presentations/rxjava-spring-boot
  2. Introduction to Reactive Programming - http://www.infoq.com/presentations/rxjava-reactor


Tags: RxJava SpringBoot
Views: 751
Register for more exciting articles

Comments

Please login or register to post a comment.


There are currently no comments.