In my application I am using ingress/nginix its conflicts my backend API route.
ingress file contains default UI route using regex
/()(.*)
Above is default route and based on it it loads default page of UI
UI route -
/management
At backend .Net controller level I have route prefix like in b
/api/management
For backend API, In ingress I have defined route like
/api/management()(.*)
UI is rendered from /management route from management-ui-service
While calling backend API from UI we are calling backend api endpoints with http://domain/api/management/XXXX
It returns 404 with above API path,but while we call API with http://domain/api/management/api/management/XXXX (need to pass multiple time end point - /api/management) it works
How we can call it with single endpoint like
http://domain/api/management/XXXX
This may be well related to regex in path put there for no good reason.
I use ingress this way and so far it works exactly as I expect it:
- backend:
service:
name: app-api
port:
number: 80
path: /api-manage/
pathType: Prefix
- backend:
service:
name: app-ui
port:
number: 80
path: /manage/
pathType: Prefix
This way I can refer to https://api.mysite.io/manage or https://api.mysite.io/api-manage/ and land exactly where I'm supposed to.
Yes, it is formatted different than your example, but you should be able to adapt it to your configuration.
Related
My NuxtJS applications makes HTTP request to a backend API. I am using nuxtjs/axios pluging to make these requests. I have configured base URL for API in nuxt.config.js like below
axios: {
baseURL: process.env.BASE_URL,
},
In Local, I have a .env like below
BASE_URL=http://localhost:8080
On AWS ECS Container, I have declared environment variable with
Key: BASE_URL and Value: https://example.com
On running the application following happens
When application is server-side rendered, base URL for API is resolved correctly e.g https://example.com/previews
When application is client-side rendered, base URL for API is not resolved to https://example.com but rather to the same IP address that my web application is accessible on.
So, what I understand might be happening is, that the process.env.BASE_URL is not getting passed from the server-side(NodeJS server) to client-side(Web Browser). Hence it is falling back to the application's IP address.
Any idea why such a behavior and how to pass the environment variable to client-side as well? Or what might be causing this.
Thanks.
I am using Spring Cloud Gateway as an API-Gateway and also as a webserver hosting the static files (html/js/css) of an Vue.js SPA.
Preclaimer: I'm not able to change this (bad) architecture due to organisational constraints.
Currently, I'm using the default Vue Router hash mode, meaning client-side routing of the Vue app is accomplished via an URL hash like
http://hostname/#/route?parameter1=true
Because the Spring Cloud Gateway also acts as an Authentication gateway, it redirects to an OAuth2/OpenID SSO server, and by doing that, the route information of the URL hash is dropped after the redirect.
I'm trying to change this behaviour by switching to Vue Router's history mode, which would enable URLs like
http://hostname/route?parameter1=true
and therefore, routing information would "survive" SSO redirects.
To do that, Vue Router documentation includes some examples for additional Webserver configuration (like mod_rewrite for Apache etc.).
Sadly there is no example included for my very special case ;-)
I scanned the documentation of Spring Cloud Gateway, but didn't find a match for this case.
So in short:
Is it possible to configure Spring Cloud Gateway to match Vue Router's history mode requirements?
You could fix it from the Spring Boot side. I mean, you could:
Enable the Vue Router history mode like explained in the documentation here
Build a Spring Boot forwarding controller like this:
#RequestMapping(value = "{_:^(?!index\\.html|api).$}")
public String redirectApi() {
LOG.info("URL entered directly into the Browser, so we need to redirect...");
return "forward:/";
}
It basically forwards all routes to front end except: /, /index.html, /api, /api/**.
Here you can find a more detailed example.
It can be done with a custom RouterFunction:
#Bean
public RouterFunction<ServerResponse> vueHistoryModeCatchAllRoute(
#Value("classpath:/static/index.html") final Resource indexHtml) {
HandlerFunction<ServerResponse> serveIndexHtmlFunction = request -> ok().contentType(MediaType.TEXT_HTML)
.bodyValue(indexHtml);
String firstApiSegmentExcludes = "api|actuator|js|img|css|fonts|favicon\\.ico";
return route(GET("/{path:^(?!" + firstApiSegmentExcludes + ").*}"), serveIndexHtmlFunction)
.and(route(GET("/{path:^(?!" + firstApiSegmentExcludes + ").*}/**"),
serveIndexHtmlFunction));
}
This will serve the index.html (containing the Vue.js app) for all requests, which do not match one of the excluded paths (firstApiSegmentExcludes).
Let's say I have a Foo service that accepts requests like:
http://foo-service/bar/baz
...and returns HATEOAS-style responses:
{
"self": "http://foo-service/bar/baz"
}
(Yes it should be links, href, etc - I'm simplifying for this question).
Now suppose I want to put that behind a reverse-proxy that also rewrites URI paths:
http://router/foo/bar/baz
(Here, I'm detecting the path starts with /foo/..., and so the reverse-proxy knows what service to route to. I would expect the self link to be "http://router/foo/bar/baz", even though the reverse-proxy actually made a request to http://foo-service/bar/baz).
I know about the Host: and X-Forwarded-Host: headers for specifying what the original request host was.
What is the correct header (or more generally, what is the correct way) for specifying the original path?
Finally found a possible answer: it seems to be X-Forwarded-Prefix.
eg: HATEOAS paths are invalid when using an API Gateway in a Spring Boot app
I am playing around with Zuul but there seems to be something fundamental I don't understand.
Per the documentation (http://cloud.spring.io/spring-cloud-netflix/spring-cloud-netflix.html), The following Zuul configuration should cause all http calls to "/myusers" to be forwarded to the "users" service.
zuul:
routes:
users: /myusers/**
I have a similar scenario but it simply doesn't work. My configuration is:
zuul:
route:
stores: /california/**
The service Id is "stores" and it has a URL called "/hello". When I hit:
http://localhost:8765/california/hello,
I get the Spring Boot 404 error message. However, things work very well if I replace california with stores, resulting in the following configuration:
zuul:
route:
stores: /stores/**
In this case, if I call
http://localhost:8765/stores/hello,
Things work just fine. So, it looks as if the prefix of the URL has to match the ID of the service. Is that the expected behavior? What am I missing?
I am using the Zuul 1.0.0.BUILD-SNAPSHOT.
On a aisde note, I did notice that the discovery client is now built in into Zuul. Is there a way to disable it if I don't want to run Eureka?
Oh my goodness, it should of course be
zuul:
routes:
instead of
zuul:
route:
Problem:
I am trying to call the ApiController from localhost:xxxx/Home/TestPage and get a 404 that the Requested URL: /Home/api/Test cannot be found.
If I make this call from the Index.cshtml page it works fine and I can navigate to localhost:xxxx/api/Test and see the desired JSON. I've tried adding ~/ to my MapHttpRoute routeTemplate but that throws an exception.
Question:
How do I remove /Home from the URL request?
Another example would be if I am on the page localhost:xxxx/People/TestPage and I want to hit multiple URIs such as localhost:xxxx/api/Hobbies, localhost:xxx/api/Pets and locahost:xxx/api/Vehicles. How would I set up the custom routing to handle this? As of right now with the default routes, I get the error that it can't find /People/api/Hobbies and so forth.
SOLUTION (Possibly):
I created a custom MapHttpRoute with the routeTemplate: "{page}/api/{controller}/{id}" and it works but I don't completely understand WHY and if this is good practice or not.
Home is your default HTTP controller. Home/api/Test is not a valid Web API controller route unless you have created custom routes. The out of the box default web api route is api/{controller}/{id}. So, if you had an API controller called home, it's URL would be localhost/api/home/id