Istio Virtual Service gives 404 if passed @RequestParam in API end points routing

9/16/2021

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
-- N K Shukla
azure-aks
istio
kubernetes
spring-boot

3 Answers

9/16/2021

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
-- N K Shukla
Source: StackOverflow

9/16/2021

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"
-- user140547
Source: StackOverflow

9/16/2021

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.

-- Mikołaj Głodziak
Source: StackOverflow