Spring REST 与 Zuul 代理

http://www.baeldung.com/spring-rest-with-zuul-proxy
作者: Eugen Paraschiv
译者: http://oopsguy.com

1、概述

在本文中,我们将探索前端接纳与独立安排的 REST API 之间的通信。

本文目的在于釜底抽薪 CORS 和浏览器的同源策略限制,允许 UI 调用
API,尽管它们不是同源

大抵,我们将创制三个单身的应用程序 — 一个 UI 应用程序和一个简单的 REST
API,大家将运用 UI 应用程序中的 Zuul 代理来代劳对 REST API 的调用。

Zuul 是 Netflix 的一个遵照 JVM 的路由和服务端负载均衡器。Spring Cloud
与内嵌式 Zuul 代理可以很好地融为一体工作 — 这次我们也将运用他们。

2、Maven 配置

首先,我们需要加上一个来源 Spring Cloud 的 zuul 援助到我们的 UI
应用程序的 pom.xml 中:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zuul</artifactId>
    <version>1.0.4.RELEASE</version>
</dependency>

3、Zuul Properties

接下去,我们需要配备 Zuul,由于大家采纳 Spring Boot,大家将在
application.yml 中开展布局:

zuul:
  routes:
    foos:
      path: /foos/**
      url: http://localhost:8081/spring-zuul-foos-resource/foos

注意:

  • 我们正在代理我们的资源服务器 Foos
  • /foos/ 伊始的 UI 的兼具请求都将路由到我们的 Foos
    资源服务器:http://
    loclahost:8081/spring-zuul-foos-resource/foos/

4、API

俺们的 API 应用程序是一个粗略的 Spring Boot 应用程序。

在本文中,我们考虑将 API 部署至运行在 8081 端口上的服务器中。

先是定义我们要采纳的资源的 DTO:

public class Foo {
    private long id;
    private String name;

    // standard getters and setters
}

和一个简短的控制器:

@Controller
public class FooController {

    @RequestMapping(method = RequestMethod.GET, value = "/foos/{id}")
    @ResponseBody
    public Foo findById(
      @PathVariable long id, HttpServletRequest req, HttpServletResponse res) {
        return new Foo(Long.parseLong(randomNumeric(2)), randomAlphabetic(4));
    }
}

5、UI 应用程序

我们的 UI 应用程序也是一个简便的 Spring Boot 应用程序。

在本文中,我们考虑将 UI 部署至运行在 8080 端口上的服务器中。

我们从 index.html 起先 — 使用了几许 AngularJS:

<html>
<body ng-app="myApp" ng-controller="mainCtrl">
<script src="angular.min.js"></script>
<script src="angular-resource.min.js"></script>

<script>
var app = angular.module('myApp', ["ngResource"]);

app.controller('mainCtrl', function($scope,$resource,$http) {
    $scope.foo = {id:0 , name:"sample foo"};
    $scope.foos = $resource("/foos/:fooId",{fooId:'@id'});

    $scope.getFoo = function(){
        $scope.foo = $scope.foos.get({fooId:$scope.foo.id});
    }  
});
</script>

<div>
    <h1>Foo Details</h1>
    {{foo.id}}
    {{foo.name}}
    <a href="#" ng-click="getFoo()">New Foo</a>
</div>
</body>
</html>

这边最着重的地方是我们怎么运用相对 URL 来访问 API!

请记住,API 应用程序未布置在与 UI
应用程序相同的服务器上,于是不能透过相对 URL
工作
,假使没有选择代理,该 UI 应用程序将不可能正常办事。

唯独,假如采纳代理服务器,我们可以透过 Zuul 代理来访问 Foo
资源,该代理配置为将那么些请求路由到实在部署 API 的岗位。

说到底,指引应用程序:

@EnableZuulProxy
@SpringBootApplication
public class UiApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(UiApplication.class, args);
    }
}

除去简单的指导注脚,请小心,我们运用 Zuul
代理的诠释启用情势,这相当酷,而且干净简洁。

6、测试路由

现行,让大家来测试 UI 应用程序,如下所示:

@Test
public void whenSendRequestToFooResource_thenOK() {
    Response response = RestAssured.get("http://localhost:8080/foos/1");

    assertEquals(200, response.getStatusCode());
}

7、自定义 Zuul Filter

有多个 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 Filter

最后,让大家测试以担保我们自定义的过滤器可以健康工作 — 首先我们将在
Foos 资源服务器上修改 FooController

@Controller
public class FooController {

    @GetMapping("/foos/{id}")
    @ResponseBody
    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 往后自 UI 应用程序的请求路由到 REST
API。大家中标地缓解了 CORS 和同源策略,我们还定制和扩张了 HTTP 请求。

本课程的总体兑现可以在项目
GitHub

中找到 — 这是一个遵照 Maven 的项目,所以应该很容易导入和运行。

原文项目示范代码

https://github.com/eugenp/tutorials/tree/master/spring-zuul

相关文章