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;
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.
- Reactive Streams (Observable in RxJava)
- 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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Component | |
public class UserService { | |
public Observable<User> findAll() { | |
return Observable.<User>from(new User[] {new User("Shazin", 29), new User("Shahim", 29)}); | |
} | |
public Observable<User> 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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@RestController | |
@RequestMapping("/user") | |
public class UserController { | |
@Autowired | |
private UserService userService; | |
@RequestMapping(method = RequestMethod.GET) | |
public Observable<List<User>> find() { | |
return userService.findAll().toList(); | |
} | |
@RequestMapping(value="/name/{name}", method = RequestMethod.GET) | |
public Observable<List<User>> findByName(@PathVariable String name) { | |
return userService.findByName(name).toList(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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<Object> deferredResult = new DeferredResult<Object>(); | |
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
- Introducing RxJava into a Spring Boot REST API - http://www.infoq.com/presentations/rxjava-spring-boot
- Introduction to Reactive Programming - http://www.infoq.com/presentations/rxjava-reactor
Trackbacks/Pings