Rerouted HTTP Requests went through API Gateways again?

Hi there, when I followed the example of api gateway example
I’m confused about ./api-gw/ingress-hashicups-frontend.yaml setting

apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
  name: route-hashicups
  namespace: default
spec:
  parentRefs:
  - name: api-gateway
    namespace: consul
  rules:
  - matches:
    - path:
        type: Exact
        value: /hashicups
    backendRefs:
    - kind: Service
      name: frontend
      namespace: default
      port: 3000
    filters:
      - type: URLRewrite
        urlRewrite:
          path:
            replacePrefixMatch: /
            type: ReplacePrefixMatch

seems like urlRewrite rule will re-route request from /hashicups to /
My expectation is that after re-route the request to /, the request will send directly to the backend service which will handle the request at path “/”, but in reality that request will go through API gateway again before sending to the backend service.

I’m not sure if this is by design or a potential bug. It borthered me so much because now I have to explicitly write my backend service handler to handle path like “service-name/endpoint” instead of just “/endpoint”, or add an extra layer of nginx before my backend service to handle that stuff.

Im super appreciate if anyone could give me any hints about this situation.

Hi @ChocolateAceCream! Your expectation – that the request should be forwarded to the backend which will see /endpoint instead of /service-name/endpoint – is how this should work.

I wasn’t sure so wanted to check: are you saying that you’ve confirmed that the request goes through the API gateway again, or are you just asking?

1 Like

Hi there,

Thanks for your confirmation. I actually tested my thought, and confirmed that what you said is right. However, only one special case caused me trouble—re-route request to “/”.
e.g.

test case #1

re-route my path from /str-service-api to /api and catch the request with

mux.Handle(“GET /api/health”, healthHandler).

  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /str-service-api
    backendRefs:
    - kind: Service
      name: str-service
      namespace: default
      port: 3300
    filters:
      - type: URLRewrite
        urlRewrite:
          path:
            replacePrefixMatch: /api
            type: ReplacePrefixMatch

It works as expected.

Test case #2

However, if i try to re-route my request to “/” like the following and handle the request as

mux.Handle(“GET /health”, healthHandler)

 rules:
  - matches:
    - path:
        type: PathPrefix
        value: /str-service-api
    backendRefs:
    - kind: Service
      name: str-service
      namespace: default
      port: 3300
    filters:
      - type: URLRewrite
        urlRewrite:
          path:
            replacePrefixMatch: /
            type: ReplacePrefixMatch

I’m not able to catch the request. So I’m wondering if there’s any limitations on re-routing to “/”

For test case #1, ingress log is

192.168.65.3 - - [23/Apr/2024:01:10:04 +0000] “GET /str-service-api/health HTTP/1.1” 200 17 “-” “Apifox/1.0.0 (https://apifox.com)” 192 0.005 [consul-api-gateway-80] 10.1.3.249:80 17 0.005 200 c0ace04e3b6bd00934ad7ee885a2e8d2

For test case #2, ingress log is

192.168.65.3 - - [23/Apr/2024:01:06:56 +0000] “GET /str-service-api/health HTTP/1.1” 301 42 “-” “Apifox/1.0.0 (https://apifox.com)” 192 0.002 [consul-api-gateway-80] 10.1.3.249:80 42 0.001 301 c13160bf89caa72985b0da01eb7f348a
192.168.65.3 - - [23/Apr/2024:01:06:56 +0000] “GET /health HTTP/1.1” 404 0 “http://consul.api-gateway.local/str-service-api/health” “Apifox/1.0.0 (https://apifox.com)” 241 0.001 [consul-api-gateway-80] 10.1.3.249:80 0 0.001 404 8fcc86c500663c69581c24f0b63ab1de

That’s why I’m asking because it seems like the request went through api gateway again.

Also, from the official example, I saw two HTTPRoute were specified for frontend service, including a "/’ path, so I’m a little bit confused.

Hi there,

Thanks for your confirmation. I actually tested my thought, and confirmed that what you said is right. However, only one special case caused me trouble—re-route request to “/”.
e.g.

test case #1

re-route my path from /str-service-api to /api and catch the request with

mux.Handle(“GET /api/health”, healthHandler).

  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /str-service-api
    backendRefs:
    - kind: Service
      name: str-service
      namespace: default
      port: 3300
    filters:
      - type: URLRewrite
        urlRewrite:
          path:
            replacePrefixMatch: /api
            type: ReplacePrefixMatch

It works as expected.

Test case #2

However, if i try to re-route my request to “/” like the following and handle the request as

mux.Handle(“GET /health”, healthHandler)

 rules:
  - matches:
    - path:
        type: PathPrefix
        value: /str-service-api
    backendRefs:
    - kind: Service
      name: str-service
      namespace: default
      port: 3300
    filters:
      - type: URLRewrite
        urlRewrite:
          path:
            replacePrefixMatch: /
            type: ReplacePrefixMatch

I’m not able to catch the request. So I’m wondering if there’s any limitations on re-routing to “/”

For test case #1, ingress log is

192.168.65.3 - - [23/Apr/2024:01:10:04 +0000] “GET /str-service-api/health HTTP/1.1” 200 17 “-” “Apifox/1.0.0 (https://apifox.com)” 192 0.005 [consul-api-gateway-80] 10.1.3.249:80 17 0.005 200 c0ace04e3b6bd00934ad7ee885a2e8d2

For test case #2, ingress log is

192.168.65.3 - - [23/Apr/2024:01:06:56 +0000] “GET /str-service-api/health HTTP/1.1” 301 42 “-” “Apifox/1.0.0 (https://apifox.com)” 192 0.002 [consul-api-gateway-80] 10.1.3.249:80 42 0.001 301 c13160bf89caa72985b0da01eb7f348a
192.168.65.3 - - [23/Apr/2024:01:06:56 +0000] “GET /health HTTP/1.1” 404 0 “http://consul.api-gateway.local/str-service-api/health” “Apifox/1.0.0 (https://apifox.com)” 241 0.001 [consul-api-gateway-80] 10.1.3.249:80 0 0.001 404 8fcc86c500663c69581c24f0b63ab1de

That’s why I’m asking because it seems like the request went through api gateway again.

Also, from the official example, I saw two HTTPRoute were specified for frontend service, including a "/’ path, so I’m a little bit confused.