google-cloud-platformgoogle-app-engineyamlurl-routing

AppEngine Dispatch rules not applied in order for hostnames?


I have a bunch of AppEngine services in a GCP project. Let's call them red-service, green-service and default, with the project being myproject.

According to the docs, the standard way to reach a specific service is hitting:

https://SERVICE_ID-dot-PROJECT_ID.REGION_ID.r.appspot.com

In my case I was normally hitting red-service by sending requests to:

https://red-service-dot-myproject.ey.r.appspot.com

As I created more services, I started looking into custom routing. Following the documentation for the dispatch.yaml file, I wrote the follwing:

dispatch:
  # Route hostname
  - url: "red-service-dot-myproject.ey.r.appspot.com/"
    service: red-service   

  # Route auth
  - url: "*/auth/api/*"
    service: green-service
    
  # Route API requests to default
  - url: "*/api/*"
    service: default

  # Route everything else to green-service
  - url: "*/*"
    service: green-service

Dispatch rules are order dependent, and only the first rule that matches a URL will be applied.

And yet, all the requests sent to:

red-service-dot-myproject.ey.r.appspot.com/auth

started hitting the green-service, as if the second or fourth match were somehow "stronger".

As a workaround I now explicitly prefix each route with the hostname:

dispatch:
  # Route hostname
  - url: "red-service-dot-myproject.ey.r.appspot.com/"
    service: red-service   

  # Route auth
  - url: "myproject.ey.r.appspot.com/auth/api/*"
    service: green-service

  # Route API requests to default
  - url: "myproject.ey.r.appspot.com/api/*"
    service: default

  # Route everything else to green-service
  - url: "myproject.ey.r.appspot.com/*"
    service: green-service

And surprisingly, this works out of the box.

What's wrong with my attempt? Shouldn't the first rule match even before explicit hostnames prefixes?

EDIT: fixed current dispatch to a more meaningful one


Solution

  • I think I figured it out.

    The broad matchers were indeed hiding the "standard" per service routing.
    So this dispatch is what I was looking for in order to keep the old service routing intact during the migration:

    dispatch:
    
      # Route auth
      - url: "myproject.ey.r.appspot.com/auth/api/*"
        service: green-service
    
      # Route API requests to default
      - url: "myproject.ey.r.appspot.com/api/*"
        service: default
    
      # Route everything else to green-service
      - url: "myproject.ey.r.appspot.com/*"
        service: green-service
    

    So request sent directly to red-service-dot-myproject.ey.r.appspot.com/* will keep being served by the red-service, regardlessly of the pattern.

    Thanks to @J_Dubu and @DazWilkin suggestions for making me rethink this mechanism.