Nginx location with regex in the middle of path

2020-02-14 regex nginx nginx-location

i'm trying to configure Nginx to parse correctly two similar paths with a regex in it.

I have 2 services:

  • /api/v1/myservice/{var}/client
  • /api/v1/myservice/{var}/client/detail

{var} is a variable I'm reading which is working

Here my code (not using the var here):

location ~ /api/v1/myservice/(.*)/client {
     return 200 "service 1 ";
}

location ~ /api/v1/myservice/(.*)/client/detail {
     return 200 "service 2";
}

When I run curl like the following:

curl http://localhost/api/v1/myservice/623723852/client/detail

I see the response from the first location: "Service 1"

What Am I doing wrong? thanks

Answers

No need to have nested locations as in the other answer. The nested locations in NGINX often give a false impression about directives' inheritance. More often than not, they are not inherited, because NGINX chooses one specific location anyway. For these reasons, if you can, avoid nested locations.

You can simply change the order of locations so that the more specific one goes first. NGINX will match the one that appears first in the config (if they both match):

location ~ /api/v1/myservice/(.*)/client/detail {
     return 200 "service 2";
}

location ~ /api/v1/myservice/(.*)/client {
     return 200 "service 1 ";
}

Alternatively, somewhat better (for performance reasons), you can adjust your regexes for more exact matching. Then the placement in configuration won't matter:

location ~ ^/api/v1/myservice/(.*)/client$ {
     return 200 "service 1 ";
}

location ~ ^/api/v1/myservice/(.*)/client/detail$ {
     return 200 "service 2";
}

Related