我希望默认将发送到我的nginx服务器的所有请求路由到我的后端应用程序,但是有选择地将带有GET HTTP谓词的API请求发送到由content_by_lua
nginx指令支持的基于OpenResty Lua的REST API。
我已成功地使用以下配置根据URL前缀将所有API请求路由到Lua API(请注意,这不会考虑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请求,以便除了GET之外的任何HTTP动词请求(如POST,PUT,DELETE等)仍然路由到后端,而GET请求单独路由到Lua API位置。
基于其他一些帖子,博客和文档(以及听到the if
directive is frowned upon),我尝试使用limit_except
指令,但是nginx服务器在启动时崩溃,因为它似乎是{{1 }}指令不是为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
指令时,根据URL前缀和 HTTP动词有选择地在nginx中路由的最佳方法是什么?
答案 0 :(得分:2)
我使用if
指令实现了特定URL GET操作的条件路由,即使根据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")';
}
}
}