Идея этого поста, первого из серии, состоит в том, чтобы продемонстрировать, как написать веб-службу Spring Boot Restful, которая получает доступ к удаленному API реактивным способом. Мое намерение состоит в том, чтобы добавить больше функций, таких как кэширование и база данных, всегда используя реактивную парадигму. В этом первом я опишу, как вы можете начать с нуля до того момента, когда у вас будет функциональный веб-сервис.
приступая к работе
Я основал это на весеннем уроке Создание реактивного веб-сервиса RESTful и создание его с нуля, копирование только начального файла сборки Gradle. Структура проекта выглядит следующим образом.
Я создал класс приложения Spring Boot по умолчанию, единственным отличием является аннотация @Componentscan , указывающая на базовый пакет приложения.
package dev.alexladeira.springboot.reactive; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ComponentScan; @SpringBootApplication @ComponentScan(basePackages = {"dev.alexladeira.springboot.reactive"}) public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
Теперь игра начинается!
Написание класса маршрутизатора
Я подумал, что класс маршрутизатора, в который я помещаю маршрут, который вы собираетесь предоставить, это простой класс, который создает связь между сервисом, который я предоставлял, и обработчиком, который я создаю для обработки запроса.
package dev.alexladeira.springboot.reactive.routes; import dev.alexladeira.springboot.reactive.handlers.GoogleBooksHandler; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.reactive.function.server.RequestPredicates; import org.springframework.web.reactive.function.server.RouterFunction; import org.springframework.web.reactive.function.server.RouterFunctions; import org.springframework.web.reactive.function.server.ServerResponse; @Configuration @ComponentScan({"handlers"}) public class SearchRouter { @Bean public RouterFunctionsearch(GoogleBooksHandler googleBooksHandler) { return RouterFunctions.route(RequestPredicates.GET("/search"), googleBooksHandler::search); } }
До сих пор мне не нужно было использовать Пружинный реактор , это изменилось, когда я написал обработчик.
Написание Обработчика и классов обслуживания
Я создал обработчик для обработки запроса, вызова внешнего ресурса и создания ответа. Здесь я получил Поисковый запрос из объекта запроса и передайте его службе, которая отвечает за возврат некоторой информации о книгах, в которой есть слово, которое я передал в качестве параметра, в этом примере я использовал API Google Книг .
package dev.alexladeira.springboot.reactive.handlers; import dev.alexladeira.springboot.reactive.domain.google.GoogleBook; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.ComponentScan; import org.springframework.stereotype.Component; import org.springframework.web.reactive.function.BodyInserters; import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.web.reactive.function.server.ServerResponse; import reactor.core.publisher.Mono; import dev.alexladeira.springboot.reactive.services.GoogleBooksService; import java.util.ArrayList; import java.util.List; @Component @ComponentScan({"services"}) public class GoogleBooksHandler { @Autowired private GoogleBooksService googleBooksService; public Monosearch(ServerRequest request) { String searchTerm = request.queryParam("searchTerm").orElse(null); return searchTerm != null ? ServerResponse.ok().body(BodyInserters.fromPublisher(this.googleBooksService.getBooksBy(searchTerm).reduce(new ArrayList (), (list, googleBookServiceResponse) -> { list.addAll(googleBookServiceResponse.items); return list; }), List.class)) : ServerResponse.badRequest().build(); } }
Задача метода поиска состоит в том, чтобы просто получить книги из API Google Books, затем сократить их до списка GoogleBooks типа, класса java, который содержит только ту информацию, которую я хочу, чтобы служба возвращала, и создать ответ. Если служба принимает и опустошает вызов (без каких-либо параметров), то выдается ошибка.
Класс обслуживания выглядит следующим образом: вызов API через WebClient объект
package dev.alexladeira.springboot.reactive.services; import dev.alexladeira.springboot.reactive.domain.google.GoogleBookServiceResponse; import org.springframework.stereotype.Service; import org.springframework.web.reactive.function.client.WebClient; import reactor.core.publisher.Flux; @Service public class GoogleBooksService implements GenericService{ private WebClient webClient = WebClient.builder().baseUrl("https://content.googleapis.com").build(); @Override public Flux getBooksBy(String searchTerm) { return this.webClient.get().uri(uriBuilder -> uriBuilder .path("/books/v1/volumes") .queryParam("q", searchTerm) .queryParam("maxResults", MAX_RESULTS) .build()).retrieve().bodyToFlux(GoogleBookServiceResponse.class).timeout(TIMEOUT); } }
Этот класс расширяет Универсальный сервис , класс, созданный для концентрации некоторой информации, которая будет использоваться другими сервисами, которые я создам в будущем, константы MAX_RESULTS и TIMEOUT.
Вывод… на сегодня
Пришло время запустить сервер и посмотреть результаты, наведите свой браузер на http://localhost:8080 , если все прошло хорошо, вы увидите это:
[{"volumeInfo":{"title":"Learning Spring Boot 2.0","authors":["Greg L. Turnquist"],"printType":"BOOK"}},{"volumeInfo":{"title":"Spring Boot 2.0 Projects","authors":["Mohamed Shazin Sadak ath"],"printType":"BOOK"}},{"volumeInfo":{"title":"Spring: Microservices with Spring Boot","authors":["Ranga Rao Karanam"],"printType":"BOOK"}},{"volumeInfo":{"title":"Pro Spring Boot"," authors":["Felipe Gutierrez"],"printType":"BOOK"}},{"volumeInfo":{"title":"Mastering Spring Boot 2.0","authors":["Dinesh Rajput"],"printType":"BOOK"}}]
Исходный код находится по адресу github.com/alexladeira/gs-reactive-rest-service . Я буду следить за этим сообщением вместе с другими, всегда стараясь показать, чему я учусь в теме весенней загрузки.
Оригинал: “https://dev.to/alexladeira/reactive-spring-boot-restful-web-service-google-books-api-4blg”