Как перейти к директиве nginx content_by_lua в зависимости от действия HTTP и префикса URL?
Я бы хотел, чтобы все запросы, отправленные на мой сервер nginx, по умолчанию использовались в моем бэкэнд-приложении, но выборочно отправлять запросы API с глаголами GET HTTP в REST API на основе OpenResty Lua, поддерживаемый content_by_lua
директива nginx.
Я успешно смог направить все запросы API к API Lua на основе их префикса URL, используя следующую конфигурацию (обратите внимание, что это не учитывает HTTP-глагол):
http {
upstream backend {
server localhost:8080;
}
server {
listen 80;
location / {
# Send all requests to the backend application
proxy_pass http://backend;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header CLIENT_IP $remote_addr;
proxy_set_header HTTP_CLIENT_IP $remote_addr;
proxy_redirect off;
}
location /api {
# Send any URL with the /api prefix to the nginx Lua API application
content_by_lua '
require("lapis").serve("app")
';
}
}
}
Но, как я уже говорил выше, я бы хотел еще больше ограничить запросы API, чтобы любые запросы с HTTP-глаголами, отличными от GET (например, POST, PUT, DELETE и т. Д.), По-прежнему направлялись на серверную часть, а только запросы GET маршрутизировались. в местоположение Lua API.
На основании некоторых других постов, блогов и документации (и слышать, что if
директива не одобряется), я пытался с помощью limit_except
директивы, но затем сервер nginx завис при запуске, как кажется, content_by_lua
Директива не была предназначена для limit_except
блоки. Здесь была моя попытка:
http {
upstream backend {
server localhost:8080;
}
server {
listen 80;
location / {
proxy_pass http://backend;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header CLIENT_IP $remote_addr;
proxy_set_header HTTP_CLIENT_IP $remote_addr;
proxy_redirect off;
}
location /api {
# Default the non-get API requests back to the backend server
proxy_pass http://backend;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header CLIENT_IP $remote_addr;
proxy_set_header HTTP_CLIENT_IP $remote_addr;
proxy_redirect off;
# Select requests that *aren't* a PUT, POST, or DELETE, and pass those to the Lapis REST API
limit_except PUT POST DELETE {
content_by_lua '
require("lapis").serve("app")
';
}
}
}
}
который быстро разбился с
nginx: [emerg] "content_by_lua" directive is not allowed here in nginx.conf:46
Каков наилучший способ выборочной маршрутизации в nginx на основе префикса URL-адреса и глагола HTTP при делегировании content_by_lua
Директива?
1 ответ
Я реализовал условную маршрутизацию определенных действий URL GET, используя if
директива, даже если это зло в соответствии с разработчиками nginx. Похоже, что это может быть одним из немногих желательных вариантов использования для if
директива, но если это не так или у кого-то есть лучший подход, пожалуйста, дайте мне знать (вот почему я не принял мой собственный ответ).
Вот файл конфигурации nginx, который в настоящее время реализует решение:
http {
upstream backend {
server localhost:3000;
}
server {
listen 80;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header CLIENT_IP $remote_addr;
proxy_set_header HTTP_CLIENT_IP $remote_addr;
proxy_redirect off;
# By default pass all the requests to the Rails app backend
location / {
proxy_pass http://backend;
}
# Delegate certain API calls to our special OpenResty Endpoints
location /api {
# Makes sure all POSTs, PUTs, and DELETE actions still get handed off to the backend
if ($request_method ~ POST|PUT|DELETE) {
proxy_pass http://backend;
}
# All that should remain are the GET and OPTIONS endpoints so send them to the OpenResty Lua backend!)
content_by_lua 'require("lapis").serve("app")';
}
}
}