How to route to my UI application using root url / using spring cloud gateway - spring

I have react based UI application running on kubernetes with root contextPath (/). When I do kubectl port-forward svc/my-ui-app 8080:8080 and then launch the application on http://localhost:8080, everything works fine.
Now I want to use spring cloud gateway to route to my application. I configured the root url (/) and /apppath like below
spec:
routes:
- filters:
- RewritePath=/apppath(?<segment>/?.*), $\{segment}
predicates:
- Path=/apppath/**
- predicates:
- Path=/
service:
name: my-ui-app
So my expection is to have http://my-domain and http://my-domain/apppath both to route to my ui application.
Whats happening is when I use http://my-domain/apppath, when the ui app internally refers to the index.js (and other image files), the url used for that evaluates to http://my-domain/apppath/index.js automatically and spring cloud gateway is able to load these files as it matches the route /apppath/** and is able to route to my application.
The problem is with the root url http://my-domain. When I hit this, the url to fetch the index.js (and images etc) evaluates to http://my-domain/index.js and spring cloud gateway does not know where to route it to as there is no route mapped for /index.js.
What do I need to do to make http://my-domain work without having to change the application code to have a contextPath explicitly set?

Related

How can I reference another app in container?

I have a docker compose with two applications:
app1 -spring boot web application with thymeleaf server pages.
app2 - another web application with 8080 port exposed.
I need to be able to address to app2 from ui of app1, like:
<a th:href="#{/app2/users}">Users</a>
But it's obvious that ui can't make redirection according to container alias.
Also the port is missing, so it needs to be configured.
Perhaps a reverse proxy can be used in that case, but looks like it can be solved much simpler. Is there any Spring component that can be used for routing or a gateway?
The resolved url of /app2 is http(s)://app1/app2 (depending on whether you have SSL configured), which isn't what you want.
Try an absolute url: http(s)://app2:8080/users. I'm not sure what th:href does, as I'm not familiar with thymeleaf, but if it doesn't work, just us plain html: Users

Equivalent of mod_proxy_html for Spring Cloud Gateway

I'm using Spring Cloud Gateway as a reverse proxy. Behind that proxy I have an Angular Web App the code of which I can't modify.
The problem is that the webapp uses relative hyperlinks so when accessing the proxied web app by URL http://localhost:8080/webapp/ the app omits the webapp part in it's hyperlinks and the hyperlinks look like http://localhost:8080/destination/ instead of http://localhost:8080/webapp/destination.Apache Httpd has module for it called mod_proxy_html that rewrites the paths in HTML content served by the proxy. Is there something similar in Spring Cloud Gateway or maybe one should use reverse proxy functionality only for REST APIs?
try:
application.yml
spring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: http://localhost:8080
predicates:
- Path=/destination
filters:
- RewritePath=/(?<segment>/?.*), /webapp/$\{segment}
https://cloud.spring.io/spring-cloud-gateway/reference/html/#the-rewritepath-gatewayfilter-factory

Dockerize vue js front end and spring boot backend and deploy on kubernetes cluster

I have developed spring boot backend and vue js front end I could successfully deploy the spring boot app and create cluster ip service for spring boot app but I have never work with NPM project on docker and kubernetes. I also have problem in Axios when I locally testing backend and frontend I give (localhost:backendport/endpoint) for axios and how can I adapt it to kubernetes. should I give cluster ip service name instead of localhost:port/endpoint -> clusteripservice/endpoint if so how can I externalize the configurations and how can I deploy both app.
here is Axios call
import axios from 'axios'
const API_URL = 'http://localhost:8084'
//const API_URL = '/'
class UserDataService {
retrieveAllUsers() {
return axios.get(`${API_URL}/user/getall`);
}
}
export default new UserDataService()
Idea is to use nginx as your app container and proxy pass to proxy to back-end. So you need to define location for your api, i.e. /api and proxy that.
Then if you are using axios, you would call all back-end endpoints on relative path, i.e.
axios.get('/api/v1/myApiPath')
So you do not need to worry about hostname in calls to back-end.
Also, for development you similarly use vue.js development settings to also proxy back-end via npm.
See my toy project here for details how it's done:
Deployment piece - https://github.com/taleodor/mafia-deployment
UI piece - https://github.com/taleodor/mafia-vue
Specifically nginx settings with proxy configuration - https://github.com/taleodor/mafia-vue/blob/master/nginx/default.conf (note that it's using websockets which you may remove if you're not using them). Specifically vue development server configuration - https://github.com/taleodor/mafia-vue/blob/master/vue.config.js.
Write up on CI / CD workings (unrelated to your question but maybe useful) - https://itnext.io/building-kubernetes-cicd-pipeline-with-github-actions-argocd-and-reliza-hub-e7120b9be870

Spring Cloud Gateway on App engine is not routing the requests to downstream services

I am trying to deploy a simple microservice application (Spring boot) in GAE. The application has 3 services -
1. Discovery Service
2. Spring Cloud Gateway
3. Customer service
I am trying to call an API through API gateway. This works fine in local machine but getting 404 in GAE hosted application.
The URL I am using is - https://Gateway-url/customer-service/version
And corresponding YAML config is :
spring:
cloud:
gateway:
routes:
-id: customer-service
uri: https://XXXXXX.customer-service.appspot.com/
predicates:
- Path=/customer-service/**
filters:
- StripPrefix=1
The URI configured in above code snippet is - target URL of GAE service.
So When I hit the https://Gateway-url/customer-service/version url in browser, I am getting 404 error but it works if I hit the direct url https://customer-service-url/version
When I changed the API Gateway configuration in the local environment, (change uri to cloud based service uri), the issue is reproducible. So I am thinking that Gateway is not able to route the requests to App Engine Service target URL.
How can I fix this problem?
I think the problem is the url that you are using in the configuration file to route your requests.
According to google cloud documentation, to call from one service to another you should use a endpoint like this
https://VERSION_ID-dot-SERVICE_ID-dot-PROJECT_ID.REGION_ID.r.appspot.com
As yo can see here
https://cloud.google.com/appengine/docs/standard/java/communicating-between-services
And it seems that the url that you are using doesn't fit int this.
Anyway I think that in a serverless environment such as app engine the best option to perform service discovery and to route requests via gateway is using the services provided by google. In case of service discovery it is done automatically and if you want a gateway you can use google cloud endpoints that have a greate integration with app engine. Because this is the gateway intended to use with these applications

How to register non Spring Boot MicroService in Eureka discovery server

I have recently installed a micro service infrastraucture based on Spring Boot + Spring Cloud.
My Spring Boot microservices register in my Eureka server and Zuul automaticaly redirects requests to them.
I have a Drupal content manager that exposes content through REST interface and I'd like it to take part in the discovery rave party. How can I have my drupal register it self in the Eureka server so Zuul redirects the corresponding calls to it?
As an ugly workaround I wonder if I can have automatic discovery and routing running in Zuul while manually configuring some REST paths to be redirected to the drupal server? (Using zuul.routes... property files)
I found that I can add manual zuul routes in bootstrap.yaml
I have tried adding it in the application yaml property files in configuration server but for some reason they are ignored when the Eureka discovery server is working.
Anyway, bootstrap.yaml works. Example:
zuul:
routes:
mta_api:
path: /mta_api/**
url: http://my-non-springboot-rest-service.com/
stripPrefix: false
You could add sidecar to your non-springboot application. This would allow Eureka support.
Source: Dead- http://cloud.spring.io/spring-cloud-static/Edgware.SR4/single/spring-cloud.html#_polyglot_support_with_sidecar
Current: https://cloud.spring.io/spring-cloud-static/Dalston.SR5/multi/multi__polyglot_support_with_sidecar.html

Resources