I want to route through Istio virtual Service to my microservice. When I use @RequestParam
based input in prefix or even in exact it throws 404
for /api/cities/{city_id}/tours
but the rest works fine.
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: app
namespace: nsapp
spec:
gateways:
- app-gateway
hosts:
- app.*.*.*
http:
- match:
- uri:
prefix: "/api/cities/{city_id}/tours"
- uri:
prefix: "/api/countries/{country_id}/cities"
- uri:
prefix: "/api/countries"
route:
- destination:
host: appservice
port:
number: 9090
Approach 1:-
I tried as below and found out it to be working, adding solution which I tested and is working. Basically, steps performed are:-
removed prefix: "/api/countries/{country_id}/cities" as /api/countries/ is common String to 2 APIs, and eventually, It is able to route to both the APIs on original appservice host respectively and same with /api/cities.
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: app
namespace: nsapp
spec:
gateways:
- app-gateway
hosts:
- app.*.*.*
http:
- match:
- uri:
prefix: "/api/cities"
- uri:
prefix: "/api/countries"
route:
- destination:
host: appservice
port:
number: 9090
Prefix matching matches literal strings.
/api/countries
also matches what you intend to match with /api/countries/{country_id}/cities
/api/cities/{city_id}/tours
however, does not work.
For more complex matching, you can use an exact and regex, as described in the VirtualService
documentation.
Maybe something like this (untested):
exact: "/api/countries"
regex: "/api/countries/[^/]*/cities"
This fragment
- uri:
prefix: "/api/cities/{city_id}/tours"
- uri:
prefix: "/api/countries/{country_id}/cities"
will be taken literally. The {city_id}
and {country_id}
will not be replaced with your custom ID. At this point, istio will look for a prefix that reads literally /api/cities/{city_id}/tours
or /api/countries/{country_id}/cities
, which doesn't exist (you get error 404). If you want to match the expression to your custom ID you have to use a regular expression. Look at this doc. There you will find information about the capabilities of the StringMatch: exact
, prefix
or regex
. You can find the syntax of the regular expressions used in istio here.
Summary:
You should change prefix
to regex
and then create your own regular expression to match your custom ID. Example:
- uri:
regex: "/api/cities/[a-zA-Z]+/tours"
- uri:
regex: "/api/countries/[a-zA-Z]+/cities"
In my example, there are only letters (upper or lower case) in the ID. Here you have to create your own regular expression based on this documentation.