我不打算解釋什麼是 ,也不解釋為什麼要使用它。我希望你已經在其他地方瞭解過,如果沒有,你可以使用 去搜索它。在本文中,我將告訴您如何使用專門針對 和`RxJava`的響應式編程。讓我們開始吧。 1.預備知識 在你繼續閱讀之前,我希望你能理解如何使用 和`RxJava REST API`。 如果不能, ...
我不打算解釋什麼是響應式編程
,也不解釋為什麼要使用它。我希望你已經在其他地方瞭解過,如果沒有,你可以使用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/books/" + 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
譯者:李東
9月福利,關註公眾號
後臺回覆:004,領取8月翻譯集錦!
往期福利回覆:001,002, 003即可領取!