I have a Zuul reverse proxy in front of my spring boot microservices, used as an API gateway.
Can the Zuul spring boot app be used to deliver static content, IE client code that calls the API gateway? I dont want to host this in a microservices or have another VM to manage for hosting content
I tried having a static folder in resources folder, but cant figure out how to map this in the application.yml responsible for routing. I dont want to route it to a NGnix or apache server, but use the embedded Tomcat of Zuul Spring boot app.
What would be the route to put in the route config, or what is the best approach for this.
Thank you
You don't have to map it in the routes config. Whatever you put in the resources/static folder will be served, as long nothing else is mapped on the same path.
Related
As a continuation of my learning of the Spring Cloud Gateway, I have created a small microservice (from Spring Boot) that serves web pages. This microservice is simple enough: it uses an application.properties file that contains the following:
server.port=8091
spring.resources.static-locations=classpath:/public/
The microservice has an index page in the resources folder, along with some style and other resources:
resources/public/index.html
resources/public/css/styling.css
resources/public/graphics/<pretty graphics files>
The Spring Cloud Gateway application uses a fairly straightforward routing configuration:
#Configuration
public class RouteConfig
{
#Bean
public RouteLocator gatewayRoutes(RouteLocatorBuilder routeLocatorBuilder)
{
return routeLocatorBuilder.routes()
.route("webdisplay",route-> route.path("/webdisplay/**").uri("localhost:8091"))
.build();
}
}
The Spring Cloud Gateway application listens on Port 8080.
When I access the simple microservice diectly:
http://localhost:8091
The index.html page is displayed as normal. Unfortunately, when I access the microservice through the Gateway:
http://localhost:8080/webdisplay
I get a blank page!
The page is blank, and the page source has nothing )(no HTML, nothing!). When using my browser's network debugger, I am seeing a response code of 200 with headers showing that HTML and other related web content is accepted. The HTML, however, is not actually getting to the browser.
Assuming that I am missing something, I went looking for examples of how to get HTML content through a Spring Cloud Gateway application. There are plenty of examples of how to get lists and text from toy microservices, and examples of how to serve static pages from a Spring Cloud Gateway application, but it appears that no one has used Spring Cloud Gateway to access webpages served by other applications! at least, no one has put up an example of doing so.
So if I am missing something that needs to be done, I haven't found it. Or perhaps this is a bug in the Gateway that needs to be reported somewhere?
Can anyone help with this? Does anyone know how to get Spring Cloud Gateway to work correctly with microservices that serve actual web content (static or dynamic)?
I am trying to access a microservice endpoint through a gateway using jhipster. The end point is from a legacy system and starts with "/d" and cannot be modified. I want the gateway to route all the requests that start with '/d/** ' to my microservice where I have a rest controller that will handle the requests that is mapped to '/api/d/**'
I'm trying to work using the documentation, so I have in my gateway the route:
zuul:
routes:
my-service-route:
path:/d/**
serviceId: serviceName
I saw that using url in zuul configuration you can specify the url directly, but I use jhipster registry so I can't approach the problem like that. As far as I understand I have to write a custom Zuul Filter or a Zuul Route Configuration that will route the requests to my service.
So I have 2 problems:
I can't access the gateway if I use a rest that begins with /d
I can't route the requests to my microservice in the way that I expect:
/d/service to be routed to my microservice where I have a restcontroller with a mapping to "/d/service".
Any info on how I should approach this is highly appreciated.
Thanks.
EDIT:
I already added my path in WebConfig source.registerCorsConfiguration("/d/**", config); and in SecurityConfiguration .antMatchers("/d/**").authenticated()
Can you try this below configuration in application.properties also you can change it to yml accordingly. so any request coming as /d/* will redirect to serviceName application instance.
zuul.routes.serviceName.serviceId=serviceName
zuul.routes.serviceName.path=/d/**
zuul.routes.serviceName.sensitive-headers=Set-Cookie,Authorization
hystrix.command.serviceName.execution.isolation.thread.timeoutInMilliseconds=600000
I have a simple Zuul app that has a single route in the application.yml to route to my microservice. It's working.
However, what I'm looking for is a more dynamic solution where I can wire up routes dynamically, either through code or perhaps by POSTing to some Zuul endpoints during a build (possibly by using springfox and a swagger definition from microservices). I could not find an API for Zuul.
I'm somewhat aware of Eureka and that seems like a solution to abstract away the routing by doing discovery. However, I'm curious if there's a solution without introducing Eureka. If there's a way to wire up these routes in Zuul during a build vs. having to edit the application.yml every time.
Thanks in advance.
If you go for Eureka this will actually work ootb. Zuul as packaged in spring cloud will automatically expose every service using its name. So if you register a service called users in Eureka, Zuul will automatically create a route /users forwarding to the instances by default. That will only allow simple url structures but should solve your problem.
Please see the official documentation for details:
By convention, a service with the ID "users", will receive requests from the proxy located at /users (with the prefix stripped). The proxy uses Ribbon to locate an instance to forward to via discovery, and all requests are executed in a hystrix command, …
I'm actually editing a blog post about this exact topic (Routing and Filtering using Spring Cloud Zuul Server) but the source code has been available and working for some time now. Feel free to use it as a reference:
https://bitbucket.org/asimio/zuulserver
https://bitbucket.org/asimio/discoveryserver (in case routes are configured with serviceIds)
https://bitbucket.org/asimio/demo-config-properties/src (Zuul-Server-refreshable.yml where routes are dynamically updated).
Look at the refreshable Spring profile settings. This Zuul setup works with both, hard-coding routes url or discovered using Eureka.
It also acting as a Spring Cloud Config client so that routes could be dynamically updated via Git, which is also covered in another blog post: Refreshable Configuration using Spring Cloud Config Server, Spring Cloud Bus, RabbitMQ and Git.
I am writing microservices with Spring Cloud.
I'm also using Zuul as the API Gateway which routes some URLs to destination services which are not registered into Eureka.
When a new route needed to be added to Zuul, we often edit the application.yml file and then restart the Zuul server.
I was wondering is there a way to add new route into Zuul without restarting the Zuul server?
I found this link useful but it only works for services registed in Erueka.
I am trying to route existing services via Spring cloud Netflix Zuul.
I have an existing service available at below url,
http://localhost:3080/query-service/getquery/1
Out of the box, with zuul I can route to the service as below,
localhost:9000/queryservice-id/queryservice/getquery/1, with "queryservice-id" as the service-id of the service when it is registered in Service Registry. The zuul port is 9000.
I do not want to change the context path and service path information when accessing the service via ZUUL.
With ZUUL, I want to access the service as below,
http://localhost:9000/query-service/getquery/1
I do want to prefix with the "serviceId". This is because I do not want to impact any existing clients of the service. Only the host and port changes, without serviceId.
I was able to accomplish it as below with ZUUL Configuration,
zuul:
routes:
query-service:
path: /query-service/**
serviceId: query-service
stripPrefix: false
With the above configuration, I am able to only use the zuul host and port, the other service specific information remains as before. Seems like stripPrefix is helping in routing without the serviceId.
But, I have a lot of services and will be adding more services too.
For every such service, I do not want to be adding a rule like that to ZUUL configuration which will mean rebuilding and recycling the ZUUL Service.
I feel there should be a simpler and better way to accomplish this, without a big effort, because the change I want to do is common to all services
Is there a way to making this change common for alll the services I want
to be routed via ZUUL.
Thanks,
As checked with the Spring Cloud Netflix team this is recommended approach.
https://github.com/spring-cloud/spring-cloud-netflix/issues/1549