您的位置:首页 > 编程语言 > Java开发

使用Spring Boot和RxJava的构建响应式REST API

2019-09-10 21:25 936 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/Developlee/article/details/100713205

我不打算解释什么是

响应式编程
,也不解释为什么要使用它。我希望你已经在其他地方了解过,如果没有,你可以使用
Google
去搜索它。在本文中,我将告诉您如何使用专门针对
Spring Boot
RxJava
的响应式编程。让我们开始吧。

1.预备知识

在你继续阅读之前,我希望你能理解如何使用

Spring Boot
RxJava
创建简单的
REST API
。如果不能,你可以在
Baeldung
上了解更多关于
Spring Boot
的知识,也可以在
AndroidHive
上了解更多关于
RxJava
的知识。它们很好地解释了这两种技术。

2.响应式REST API

构建一个只包含作者和书籍的简单

CRUD
响应式
REST API
。这些是端点:

[POST] /api/authors → 添加作者

[POST] /api/books → 添加书籍

[PUT] /api/books/{bookId} → 根据书籍id更新书籍信息

[GET] /api/books?limit={limit}&page={page} → 分页获取书籍列表

[GET] /api/book/{bookId} → 根据书籍id获取书籍详细信息

[DELETE] /api/book/{bookId} → 删除书籍

3.依赖

打开pom.xml并添加如下依赖项。

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>io.reactivex</groupId>
<artifactId>rxjava</artifactId>
<version>1.3.8</version>
</dependency>
<!--IMPORTANT!!! ADD THIS DEPENDENCY TO SOLVE HttpMediaNotAcceptableException-->
<dependency>
<groupId>io.reactivex</groupId>
<artifactId>rxjava-reactive-streams</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.199</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
<version>1.18.8</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.1.5.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.25.0</version>
<scope>test</scope>
</dependency>
</dependencies>

备注:请记住,您必须添加第19-23行依赖项。如果您不添加该依赖项,那么每次您点击响应式API时都会得到

HttpMediaNotAcceptableException
。如您所见,我还添加了
mockito
作为单元测试中mock对象的依赖项。但是我将在另一篇文章中讨论单元测试。

4.服务层

对于服务层,返回值不仅仅是常规数据类型,而是我将它们封装在

RxJava
Single
(单一)数据类型中。例如,下面的代码处理新书的添加。

@Override
public Single<String> addBook(AddBookRequest addBookRequest) {
return saveBookToRepository(addBookRequest);
}
private Single<String> saveBookToRepository(AddBookRequest addBookRequest) {
return Single.create(singleSubscriber -> {
Optional<Author> optionalAuthor = authorRepository.findById(addBookRequest.getAuthorId());
if (!optionalAuthor.isPresent())
singleSubscriber.onError(new EntityNotFoundException());
else {
String addedBookId = bookRepository.save(toBook(addBookRequest)).getId();
singleSubscriber.onSuccess(addedBookId);
}
});
}
private Book toBook(AddBookRequest addBookRequest) {
Book book = new Book();
BeanUtils.copyProperties(addBookRequest, book);
book.setId(UUID.randomUUID().toString());
book.setAuthor(Author.builder()
.id(addBookRequest.getAuthorId())
.build());
return book;
}

正如您所看到的,

addBook
方法的返回值是一个封装在
RxJava
中的字符串。

5.web层

@PostMapping(
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE
)
public Single<ResponseEntity<BaseWebResponse>> addBook(@RequestBody AddBookWebRequest addBookWebRequest) {
return bookService.addBook(toAddBookRequest(addBookWebRequest))
.subscribeOn(Schedulers.io())
.map(s -> ResponseEntity.created(URI.create("/api/boo
3ff7
ks/"   s)).body(BaseWebResponse.successNoData()));
}
private AddBookRequest toAddBookRequest(AddBookWebRequest addBookWebRequest) {
AddBookRequest addBookRequest = new AddBookRequest();
BeanUtils.copyProperties(addBookWebRequest, addBookRequest);
return addBookRequest;
}

在web层中,它只是将请求转发给相应的服务,如上所示,用于处理新书的添加。

6.结束

整个代码( 单元测试)可以在GitHub上找到。

原文:https://dzone.com/articles/reactive-rest-api-using-spring-boot-and-rxjava-1

作者: Axellageraldinc A

译者:李东
------

9月福利,关注公众号​后台回复:004,领取8月翻译集锦!​往期福利回复:001,002, 003即可领取!

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: