1. Обзор
В этой статье мы рассмотрим связь между интерфейсным приложением и API REST, которые развертываются отдельно .
Цель состоит в том, чтобы обойти ограничения политики CARS и той же политики происхождения браузера и позволить пользовательскому интерфейсу вызывать API, даже если они не имеют одного и того же источника.
В основном мы создадим два отдельных приложения – приложение пользовательского интерфейса и простой REST API, и мы будем использовать прокси-сервер Zuul в приложении пользовательского интерфейса для прокси-вызовов REST API.
Zuul – это маршрутизатор на базе JVM и балансировщик нагрузки на стороне сервера от Netflix. И Spring Cloud имеет хорошую интеграцию со встроенным прокси – сервером Zuul, который мы будем использовать здесь.
Дальнейшее чтение:
Пример балансировки нагрузки с помощью Zuul и Eureka
Настройка Swagger 2 с помощью API Spring REST
Введение в документы весеннего ОТДЫХА
2. Конфигурация Maven
Во-первых, нам нужно добавить зависимость от поддержки zuul из Spring Cloud в наше приложение пользовательского интерфейса pom.xml :
org.springframework.cloud spring-cloud-starter-netflix-zuul 2.2.0.RELEASE
Последнюю версию можно найти здесь .
3. Свойства Zuul
Далее – нам нужно настроить Zuul, и поскольку мы используем Spring Boot, мы собираемся сделать это в application.yml :
zuul: routes: foos: path: /foos/** url: http://localhost:8081/spring-zuul-foos-resource/foos
Обратите внимание, что:
- Мы проксируем наш сервер ресурсов Foos.
- Все запросы из пользовательского интерфейса, начинающиеся с ” /food/ “, будут перенаправляться на наш сервер ресурсов Food по адресу http://loclahost:8081/spring-zuul-foos-resource/foos/
4. API
Наше приложение API-это простое приложение для весенней загрузки.
В этой статье мы рассмотрим API, развернутый на сервере, работающем на порту 8081.
Давайте сначала определим базовый DTO для ресурса, который мы будем использовать:
public class Foo { private long id; private String name; // standard getters and setters }
И простой контроллер:
@RestController public class FooController { @GetMapping("/foos/{id}") public Foo findById( @PathVariable long id, HttpServletRequest req, HttpServletResponse res) { return new Foo(Long.parseLong(randomNumeric(2)), randomAlphabetic(4)); } }
5. Приложение пользовательского интерфейса
Наше приложение пользовательского интерфейса также является простым приложением для весенней загрузки.
В этой статье мы рассмотрим API, развернутый на сервере, работающем на порту 8080.
Начнем с главного index.html – использование немного AngularJS:
Foo Details
{{foo.id}} {{foo.name}} New Foo
Наиболее важным аспектом здесь является то, как мы получаем доступ к API , используя относительные URL-адреса!
Имейте в виду, что приложение API не развернуто на том же сервере , что и приложение пользовательского интерфейса, поэтому относительные URL-адреса не должны работать и не будут работать без прокси-сервера.
Однако с прокси-сервером мы получаем доступ к ресурсам Foo через прокси-сервер Zuul, который, конечно, настроен для маршрутизации этих запросов туда, где фактически развернут API.
И, наконец, приложение с включенной загрузкой:
@EnableZuulProxy @SpringBootApplication public class UiApplication extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(UiApplication.class, args); } }
Помимо простой аннотации загрузки, обратите внимание, что мы также используем аннотацию в стиле enable для прокси-сервера Zuul, что довольно круто, чисто и лаконично.
6. Проверьте маршрутизацию
Теперь – давайте протестируем наше приложение пользовательского интерфейса – следующим образом:
@Test public void whenSendRequestToFooResource_thenOK() { Response response = RestAssured.get("http://localhost:8080/foos/1"); assertEquals(200, response.getStatusCode()); }
7. Пользовательский Фильтр Zuul
Доступно несколько фильтров Zuul , и мы также можем создать ваш собственный:
@Component public class CustomZuulFilter extends ZuulFilter { @Override public Object run() { RequestContext ctx = RequestContext.getCurrentContext(); ctx.addZuulRequestHeader("Test", "TestSample"); return null; } @Override public boolean shouldFilter() { return true; } // ... }
Этот простой фильтр просто добавляет заголовок ” Test ” к запросу – но, конечно, мы можем получить столько сложностей, сколько нам нужно, чтобы увеличить наши запросы.
8. Проверьте Пользовательский фильтр Zuul
Наконец, давайте проверим, работает ли наш пользовательский фильтр – сначала мы изменим наш FooController на сервере ресурсов Foos:
@RestController public class FooController { @GetMapping("/foos/{id}") public Foo findById( @PathVariable long id, HttpServletRequest req, HttpServletResponse res) { if (req.getHeader("Test") != null) { res.addHeader("Test", req.getHeader("Test")); } return new Foo(Long.parseLong(randomNumeric(2)), randomAlphabetic(4)); } }
А теперь – давайте проверим это:
@Test public void whenSendRequest_thenHeaderAdded() { Response response = RestAssured.get("http://localhost:8080/foos/1"); assertEquals(200, response.getStatusCode()); assertEquals("TestSample", response.getHeader("Test")); }
9. Заключение
В этой статье мы сосредоточились на использовании Zuul для маршрутизации запросов из приложения пользовательского интерфейса в REST API. Мы успешно работали с ЯДРАМИ и политикой одного и того же источника, а также нам удалось настроить и дополнить HTTP-запрос при передаче.
полную реализацию этого учебника можно найти в проекте GitHub – это проект на основе Maven, поэтому его должно быть легко импортировать и запускать как есть.