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.
Einrichten von Swagger 2 mit einer Spring REST-API
Erfahren Sie, wie Sie eine Spring REST-API mit Swagger 2 dokumentieren.
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.
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:
-
Wir stellen einen Proxy auf unseren RessourcenserverFoos.
-
Alle Anforderungen von der Benutzeroberfläche, die mit "/foos/" beginnen, werden umhttp://loclahost:8081/spring-zuul-foos-resource/foos/ an unserenFoos-Ressourcenserver weitergeleitet
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:
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.