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

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

1.预备知识

在你继续阅读之前,我希望你能理解如何使用Spring BootRxJava创建简单的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并添加如下依赖项。


        
            org.springframework.boot
            spring-boot-starter-web
            2.1.5.RELEASE
        
        
            org.springframework.boot
            spring-boot-starter-data-jpa
            2.1.5.RELEASE
        
        
            io.reactivex
            rxjava
            1.3.8
        
    
        
            io.reactivex
            rxjava-reactive-streams
            1.2.1
        
        
            com.h2database
            h2
            1.4.199
        
        
            org.projectlombok
            lombok
            true
            1.18.8
        
        
            org.springframework.boot
            spring-boot-starter-test
            2.1.5.RELEASE
            test
        
        
            org.mockito
            mockito-core
            2.25.0
            test
        
    

备注:请记住,您必须添加第19-23行依赖项。如果您不添加该依赖项,那么每次您点击响应式API时都会得到HttpMediaNotAcceptableException。如您所见,我还添加了mockito作为单元测试中mock对象的依赖项。但是我将在另一篇文章中讨论单元测试。

4.服务层

对于服务层,返回值不仅仅是常规数据类型,而是我将它们封装在RxJavaSingle(单一)数据类型中。例如,下面的代码处理新书的添加。

@Override
    public Single addBook(AddBookRequest addBookRequest) {
        return saveBookToRepository(addBookRequest);
    }
    private Single saveBookToRepository(AddBookRequest addBookRequest) {
        return Single.create(singleSubscriber -> {
            Optional 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> 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

作者: Axellageraldinc A

译者:李东
------

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

使用Spring Boot和RxJava的构建响应式REST API_第1张图片

你可能感兴趣的:(java,springboot,spring,cloud,微服务)