Hello all,
I'll try to build module based nginx lua apps
which loaded dynamically by main lua module i called router.lua
the concept simple just read first uri path and let module remaining path, but it still wondering whether this approach is safe and optimized for performance, my current understanding of loading lua module, if have three way of loading module
1. map routes to module name and load module in each request
local route = _M.get_route() --get current route, ex /auth => contoller = "auth"
local controller = require(m) -- "auth"
local output = controller.run()
2. load module one by one and map to routes
local auth = require "auth"
local routers = { ["auth"] = auth }
local route = _M.get_route()
local controller = routes[route.controller]
local output = controller.run()
3. preload all module in lib variable as in router.lua module currently implemented (source bellow)
any suggestion which one is better or there are other approach
nginx.conf
location /api {
default_type "application/json";
content_by_lua '
local r = require "router"
r.run()
';
}
config.lua
local _M = {}
_M.base = "api"
_M.routes = { "auth", "user" } -- this ex just to but it should be more
_M.redis = { host = "127.0.0.1", port = 6379, timeout = 1000, keep = 1024 }
return _M
router.lua
local cjson = require "cjson"
local config = require "config"
local gmatch = string.gmatch
local ngx = ngx
local redis = require "resty.redis"
local lib = {}
local function get_routes()
local result = {}
for i=1, #config.routes do
local k = config.routes[i]
lib[k] = require (k)
result[k] = true
end
return result
end
local routes = get_routes()
local _M = { _VERSION = "0.1.0" }
function _M.run()
local route = _M.get_route() --get current route
if not routes[route.controller] then return end
--local controller = require(config.route.controller)
local controller = lib[route.controller]
local config = config.redis
local r = redis:new()
r:set_timeout(config.timeout)
local ok,error = r:connect(config.host, config.port)
if not ok then ngx.log(ngx.ERR, "failed connect to redis at : ", error) return ngx.exit(500) end
local output = controller.run(r, route.action)
local ok,error = r:set_keepalive(0,config.keep)
if not ok then ngx.log(ngx.ERR,"failed to keepalive", error) end
if output then
ngx.say(cjson.encode(output))
end
end
function _M.get_route()
local uri = ngx.var.uri
local index = { "base" ,"controller","action" }
local route = { base = config.base, contoller = "auth" }
local n = 0
for w in gmatch(uri, '/(%w+)') do
n = n + 1
local path = index[n]
if n == 1 and w ~= route[path] then return ngx.exit(404) end
route[path] = w
end
return route
end
return _M