Рубрики
Без рубрики

Веб-сервис Restful с реактивной пружинной загрузкой + API Google Книг

Идея этого поста, первого из серии, состоит в том, чтобы продемонстрировать, как написать весеннюю загрузку Спокойные Мы… С тегом java, весенняя загрузка, реактивный, спокойный.

Идея этого поста, первого из серии, состоит в том, чтобы продемонстрировать, как написать веб-службу 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 RouterFunction search(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 Mono search(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”