Spring REST mit einem Zuul Proxy

Spring REST mit einem Zuul Proxy

1. Überblick

In diesem Artikel werden wir diecommunication between a front-end application and a REST API that are deployed separately untersuchen.

Ziel ist es, CORS und die Richtlinienbeschränkung für denselben Ursprung des Browsers zu umgehen und der Benutzeroberfläche zu ermöglichen, die API aufzurufen, obwohl sie nicht denselben Ursprung haben.

Grundsätzlich erstellen wir zwei separate Anwendungen - eine UI-Anwendung und eine einfache REST-API. In der UI-Anwendung verwenden wirthe Zuul proxy, um Aufrufe an die REST-API zu protokollieren.

Zuul ist ein JVM-basierter Router und Server Side Load Balancer von Netflix. Und Spring Cloud hat eine schöne Integration mit einem eingebetteten Zuul-Proxy - was wir hier verwenden werden.

Weitere Lektüre:

Ein Beispiel für Load Balancing mit Zuul und Eureka

Sehen Sie, wie der Lastenausgleich mit Netflix Zuul aussieht.

Read more

Einrichten von Swagger 2 mit einer Spring REST-API

Erfahren Sie, wie Sie eine Spring REST-API mit Swagger 2 dokumentieren.

Read more

Einführung in Spring REST Docs

In diesem Artikel wird Spring REST Docs vorgestellt, ein testgesteuerter Mechanismus zum Generieren einer Dokumentation für RESTful-Services, die genau und lesbar ist.

Read more

2. Maven-Konfiguration

Zunächst müssen wir der zuul-Unterstützung von Spring Cloud eine Abhängigkeit zu denpom.xml unserer UI-Anwendung hinzufügen:


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

3. Zuul Eigenschaften

Als nächstes müssen wir Zuul konfigurieren. Da wir Spring Boot verwenden, werden wir dies inapplication.yml tun:

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

Beachten Sie, dass:

4. Die API

Unsere API-Anwendung ist eine einfache Spring Boot-App.

In diesem Artikel wird die API betrachtet, die auf einem Server miton port 8081. bereitgestellt wird

Definieren wir zunächst das grundlegende DTO für die Ressource, die wir verwenden werden:

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

    // standard getters and setters
}

Und eine einfache Steuerung:

@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. Die UI-Anwendung

Unsere UI-Anwendung ist auch eine einfache Spring Boot-Anwendung.

In diesem Artikel wird die API betrachtet, die auf einem Server miton port 8080. bereitgestellt wird

Beginnen wir mit den wichtigstenindex.html - mit etwas AngularJS:








Foo Details

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

Der wichtigste Aspekt hierbei ist, wie wir auf die APIusing relative URLs!zugreifen

Beachten Sie, dass die API-Anwendung nicht auf demselben Server wie die UI-Anwendungso relative URLs shouldn’t work bereitgestellt wird und ohne den Proxy nicht funktioniert.

Mit dem Proxy greifen wir jedoch über den Zuul-Proxy auf die Ressourcen vonFoozu, der natürlich so konfiguriert ist, dass diese Anforderungen an den Ort weitergeleitet werden, an dem die API tatsächlich bereitgestellt wird.

Und zum Schluss die eigentlich Boot-fähige Anwendung:

@EnableZuulProxy
@SpringBootApplication
public class UiApplication extends SpringBootServletInitializer {

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

Neben der einfachen Boot-Annotation ist zu beachten, dass wir auch den Enable-Stil der Annotation für den Zuul-Proxy verwenden, der ziemlich cool, sauber und prägnant ist.

6. Testen Sie das Routing

Testen Sie nun unsere UI-Anwendung wie folgt:

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

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

7. Ein benutzerdefinierter Zuul-Filter

Es sind mehrereZuul filtersverfügbar, und wir können auch eine eigene erstellen:

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

Dieser einfache Filter fügt der Anfrage nur einen Header mit dem Namen "Test" hinzu - aber natürlich können wir so komplex werden, wie wir es brauchen, um unsere Anfragen hier zu erweitern.

8. Testen Sie den benutzerdefinierten Zuul-Filter

Lassen Sie uns abschließend testen, ob unser benutzerdefinierter Filter funktioniert. Zuerst ändern wir unsereFooController auf dem Foos-Ressourcenserver:

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

Testen wir es jetzt:

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

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

9. Fazit

In diesem Artikel haben wir uns darauf konzentriert, Zuul zum Weiterleiten von Anforderungen von einer UI-Anwendung an eine REST-API zu verwenden. Wir haben CORS und die Richtlinie für denselben Ursprung erfolgreich umgangen und es auch geschafft, die HTTP-Anforderung während der Übertragung anzupassen und zu erweitern.

Diefull implementation dieses Tutorials finden Sie inthe GitHub project - dies ist ein Maven-basiertes Projekt, daher sollte es einfach zu importieren und auszuführen sein, wie es ist.