(The situation that caused the question is pretty defined and not abstract. But I know applicable to it workarounds thus I dropped details in order to get general pipeline that answers to this question.)
Problem description: Imagine that you have one location
NGINX block and you want to have possibility to response in this block in different ways depending on requests' HTTP method. But NGINX does not support syntax like location /:POST {...}
, some more complex way is needed.
I tried to find the answer to this question and all my findings can be classificated into these groups:
Group 1: if ($request_method ...)
inside location
But If is Evil .
As for me, the pure if
way does not work without copying directives into if
clause from external "common" space. Moreover, all copied directives are not approved to be inside by NGINX's developers.
Only return
and rewrite
is approved to be inside if
but it is not enough.
Group 2: limit_except
This way is applicable if you want to restrict some methods for a location. But it does not allow distinguishing behavior for each HTTP method group for the same location.
Group 3: lets map
everything
Many if
cases can be replaced by one/two/... proper map
block(s). $request_method can also be mapped but what if it is not enough or pretty just map
several times? How, for example, to proxy_pass
requests with one HTTP method and perform try_files
for requests with the same location and another HTTP method without if
? (Not my situation, just example of two incompatible directives not allowed in if
). How to avoid 10+ map
s that can be needed for even one conditioning.
Group 4: proxying to different upstream
blocks
This way is quite complex and looks like a overkill. Moreover, if you need something else than just proxying (for endpoint selection map
is enough) you have to create a new virtual host. Also pieces of the implementation are located far apart.