Spring REST met een Zuul Proxy
1. Overzicht
In dit artikel zullen we de communicatie tussen een front-end applicatie en een REST API die afzonderlijk worden geïmplementeerd.
Het doel is om CORS en de Same Origin Policy-beperking van de browser te omzeilen en de gebruikersinterface toe te staan de API aan te roepen, ook al hebben ze niet dezelfde oorsprong.
We zullen in feite twee afzonderlijke applicaties maken - een UI-applicatie en een eenvoudige REST API, en we zullen deze gebruiken de volmacht van Zuul in de UI-applicatie om aanroepen naar de REST API te proxy.
Zuul is een JVM-gebaseerde router en server-side load balancer van Netflix. En Spring Cloud heeft een mooie integratie met een ingebouwde Zuul-proxy - dat is wat we hier zullen gebruiken.
2. Maven-configuratie
Ten eerste moeten we een afhankelijkheid toevoegen aan de zuul-ondersteuning van Spring Cloud naar onze UI-applicaties pom.xml:
org.springframework.cloud spring-cloud-starter-netflix-zuul 2.2.0.RELEASE
De laatste versie vind je hier.
3. Zuul-eigenschappen
Vervolgens moeten we Zuul configureren, en aangezien we Spring Boot gebruiken, gaan we dat doen in de application.yml:
zuul: routes: foos: path: / foos / ** url: // localhost: 8081 / spring-zuul-foos-resource / foos
Let daar op:
- We doen een proxy naar onze bronserver Foos.
- Alle verzoeken van de gebruikersinterface die beginnen met '/ foos /”Wordt doorgestuurd naar ons Foos Bronserver op // loclahost: 8081 / spring-zuul-foos-resource / foos /
4. De API
Onze API-applicatie is een eenvoudige Spring Boot-app.
In dit artikel gaan we kijken naar de API die is geïmplementeerd op een actieve server op poort 8081.
Laten we eerst de basis-DTO definiëren voor de resource die we gaan gebruiken:
openbare klasse Foo {lange privé-id; private String naam; // standaard getters en setters}
En een simpele controller:
@RestController openbare klasse FooController {@GetMapping ("/ foos / {id}") openbare Foo findById (@PathVariable lange id, HttpServletRequest req, HttpServletResponse res) {return new Foo (Long.parseLong (randomNumeric (2)), randomAlphabetic 4)); }}
5. De UI-applicatie
Onze UI-applicatie is ook een eenvoudige Spring Boot-applicatie.
In dit artikel gaan we kijken naar de API die is geïmplementeerd op een actieve server op poort 8080.
Laten we beginnen met het belangrijkste index.html - een beetje AngularJS gebruiken:
var app = angular.module ('myApp', ["ngResource"]); app.controller ('mainCtrl', function ($ scope, $ resource, $ http) {$ scope.foo = {id: 0, naam: "sample foo"}; $ scope.foos = $ resource ("/ foos / : fooId ", {fooId: '@ id'}); $ scope.getFoo = function () {$ scope.foo = $ scope.foos.get ({fooId: $ scope.foo.id});}}) ; {{foo.id}} {{foo.name}} Nieuwe Foo
Het belangrijkste aspect hier is hoe we toegang krijgen tot de API met behulp van relatieve URL's!
Houd er rekening mee dat de API-applicatie niet op dezelfde server is geïmplementeerd als de UI-applicatie, dus relatieve URL's zouden niet moeten werken, en zal niet werken zonder de proxy.
Met de proxy hebben we echter toegang tot het Foo resources via de Zuul-proxy, die natuurlijk is geconfigureerd om deze verzoeken door te sturen naar waar de API ook daadwerkelijk wordt geïmplementeerd.
En tot slot, de eigenlijk Boot-enabled applicatie:
@EnableZuulProxy @SpringBootApplication openbare klasse UiApplication breidt SpringBootServletInitializer uit {openbare statische leegte hoofd (String [] args) {SpringApplication.run (UiApplication.class, args); }}
Merk op dat we naast de eenvoudige Boot-annotatie ook de inschakelstijl van annotatie gebruiken voor de Zuul-proxy, die best gaaf, schoon en beknopt is.
6. Test de routing
Laten we nu onze UI-applicatie testen - als volgt:
@Test public void whenSendRequestToFooResource_thenOK () {Response response = RestAssured.get ("// localhost: 8080 / foos / 1"); assertEquals (200, response.getStatusCode ()); }
7. Een op maat gemaakt Zuul-filter
Er zijn meerdere Zuul-filters beschikbaar en we kunnen ook onze eigen aangepaste filters maken:
@Component public class CustomZuulFilter breidt ZuulFilter uit {@Override public Object run () {RequestContext ctx = RequestContext.getCurrentContext (); ctx.addZuulRequestHeader ("Test", "TestSample"); null teruggeven; } @Override openbare boolean shouldFilter () {return true; } // ...}
Dit eenvoudige filter voegt gewoon een koptekst toe met de naam 'Test”Op het verzoek - maar we kunnen natuurlijk zo complex worden als nodig is om hier onze verzoeken uit te breiden.
8. Test het aangepaste Zuul-filter
Laten we tot slot testen of ons aangepaste filter werkt - eerst zullen we onze FooController op Foos resource server:
@RestController openbare klasse FooController {@GetMapping ("/ foos / {id}") openbare Foo findById (@PathVariable lange id, HttpServletRequest req, HttpServletResponse res) {if (req.getHeader ("Test")! = Null) {res .addHeader ("Test", req.getHeader ("Test")); } retourneer nieuwe Foo (Long.parseLong (randomNumeric (2)), randomAlphabetic (4)); }}
Laten we het nu eens testen:
@Test public void whenSendRequest_thenHeaderAdded () {Response response = RestAssured.get ("// localhost: 8080 / foos / 1"); assertEquals (200, response.getStatusCode ()); assertEquals ("TestSample", response.getHeader ("Test")); }
9. Conclusie
In dit artikel hebben we ons gericht op het gebruik van Zuul om verzoeken van een UI-applicatie naar een REST API te sturen. We hebben met succes rond CORS en hetzelfde beleid gewerkt en we zijn er ook in geslaagd om het HTTP-verzoek tijdens de overdracht aan te passen en uit te breiden.
De volledige implementatie van deze tutorial is te vinden in het GitHub-project - dit is een op Maven gebaseerd project, dus het zou gemakkelijk te importeren en uit te voeren moeten zijn zoals het is.