REST de primavera com um proxy Zuul

REST de primavera com um proxy Zuul

1. Visão geral

Neste artigo, vamos explorar ocommunication between a front-end application and a REST API that are deployed separately.

O objetivo é contornar o CORS e a restrição da política de mesma origem do navegador e permitir que a IU chame a API, mesmo que eles não compartilhem a mesma origem.

Basicamente, criaremos dois aplicativos separados - um aplicativo de IU e uma API REST simples, e usaremosthe Zuul proxy no aplicativo de IU para chamadas de proxy para a API REST.

O Zuul é um roteador baseado em JVM e um balanceador de carga no lado do servidor da Netflix. E Spring Cloud tem uma boa integração com um proxy Zuul embutido - que é o que usaremos aqui.

Leitura adicional:

Um exemplo de balanceamento de carga com Zuul e Eureka

Veja como é o equilíbrio de carga com o Netflix Zuul.

Read more

Configurando o Swagger 2 com uma API REST do Spring

Aprenda a documentar uma API REST do Spring usando o Swagger 2.

Read more

Introdução ao Spring REST Docs

Este artigo apresenta o Spring REST Docs, um mecanismo controlado por teste para gerar documentação para serviços RESTful que é precisa e legível.

Read more

2. Configuração do Maven

Primeiro, precisamos adicionar uma dependência ao suporte zuul do Spring Cloud para opom.xml do nosso aplicativo de IU:


    org.springframework.cloud
    spring-cloud-starter-zuul
    1.0.4.RELEASE

3. Propriedades Zuul

Em seguida, precisamos configurar o Zuul e, como estamos usando o Spring Boot, faremos isso noapplication.yml:

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

Observe que:

4. A API

Nosso aplicativo de API é um aplicativo simples de inicialização de primavera.

Neste artigo, vamos considerar a API implantada em um servidor executandoon port 8081.

Vamos primeiro definir o DTO básico para o recurso que usaremos:

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

    // standard getters and setters
}

E um controlador simples:

@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. O aplicativo UI

Nosso aplicativo de interface do usuário também é um aplicativo simples de inicialização de primavera.

Neste artigo, vamos considerar a API implantada em um servidor executandoon port 8080.

Vamos começar com oindex.html principal - usando um pouco de AngularJS:








Foo Details

{{foo.id}} {{foo.name}} New Foo

O aspecto mais importante aqui é como estamos acessando a APIusing relative URLs!

Lembre-se de que o aplicativo API não é implantado no mesmo servidor que o aplicativo UI,so relative URLs shouldn’t work, e não funcionará sem o proxy.

Com o proxy, no entanto, estamos acessando os recursosFoo por meio do proxy Zuul, que é obviamente configurado para encaminhar essas solicitações para onde quer que a API esteja realmente implementada.

E, finalmente, o aplicativo realmente habilitado para inicialização:

@EnableZuulProxy
@SpringBootApplication
public class UiApplication extends SpringBootServletInitializer {

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

Além da simples anotação de inicialização, observe que estamos usando o estilo de anotação de ativação para o proxy Zuul também, que é muito legal, limpo e conciso.

6. Teste o roteamento

Agora - vamos testar nosso aplicativo de IU - da seguinte maneira:

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

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

7. Um filtro Zuul personalizado

Existem váriosZuul filters disponíveis e também podemos criar o nosso próprio:

@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;
    }
    // ...
}

Este filtro simples apenas adiciona um cabeçalho chamado “Test” à solicitação - mas é claro, podemos ficar tão complexos quanto precisarmos para aumentar nossas solicitações.

8. Teste o filtro Zuul personalizado

Finalmente, vamos testar se nosso filtro personalizado está funcionando - primeiro vamos modificar nossoFooController no servidor de recursos Foos:

@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));
    }
}

Agora - vamos testar:

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

    assertEquals(200, response.getStatusCode());
    assertEquals("TestSample", response.getHeader("Test"));
}

9. Conclusão

Neste artigo, nos concentramos em usar o Zuul para rotear solicitações de um aplicativo de interface do usuário para uma API REST. Trabalhamos com êxito em torno do CORS e da política de mesma origem e também conseguimos personalizar e aumentar a solicitação HTTP em trânsito.

Ofull implementation deste tutorial pode ser encontrado emthe GitHub project - este é um projeto baseado em Maven, portanto, deve ser fácil de importar e executar como está.