Saltar a contenido

router: Enrutador http Lua para nginx-module-lua

Instalación

Si no has configurado la suscripción al repositorio RPM, regístrate. Luego puedes proceder con los siguientes pasos.

CentOS/RHEL 7 o Amazon Linux 2

yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install lua-resty-router

CentOS/RHEL 8+, Fedora Linux, Amazon Linux 2023

dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install lua5.1-resty-router

Para usar esta biblioteca Lua con NGINX, asegúrate de que nginx-module-lua esté instalado.

Este documento describe lua-resty-router v0.1.0 lanzado el 26 de junio de 2017.


Esta biblioteca Lua es un enrutador http para el módulo ngx_lua de nginx:

http://wiki.nginx.org/HttpLuaModule

Esta biblioteca Lua aprovecha la API de cosocket de ngx_lua, que garantiza un comportamiento 100% no bloqueante.

Ten en cuenta que se requiere al menos ngx_lua 0.5.0rc29 o OpenResty 1.0.15.7.

Sinopsis

    server {
        location /test {
            content_by_lua '
                local Router = require "resty.router"
              router = Router:new()
              router:get("/a/:b/:c", function(params)
                ngx.print(params["b"].."-"..parmams["c"])
              end)
              router:post("/b/c/*.html", function(params)
                ngx.print("echo html")
              end)
              router:any("/c/d/", function(params)
                ngx.print("hello, world")
              end)
            ';
        }
    }

Métodos

El argumento key proporcionado en los siguientes métodos será automáticamente escapado de acuerdo con las reglas de escape de URI antes de enviarlo al servidor memcached.

new

syntax: r, err = router:new()

Crea un objeto enrutador, nunca devuelve un error.

route

Usando GET, POST, HEAD, PUT, PATCH, DELETE, ANY y OPTIONS

local R = require("resty.router")
local router = R:new()
router:get("/GetRoute", handler)
router:post("/PostRoute", handler)
router:head("/HeadRoute", handler)
router:put("/PutRoute", handler)
router:delete("/DeleteRoute", handler)
router:patch("/PatchRoute", handler)
router:options("/OptionsRoute", handler)
router:any("/AnyRoute", handler)
router:run()

Parámetros en la ruta

    local R = require("resty.router")
    local router = R:new()

    -- capturar todo cuando se coincide con la ruta
    router:get("/*", function(params) -- /* o * está bien
        ngx.say("capturar todo") 
        ngx.exit(200)
    end)

    -- Este manejador coincidirá con /user/john pero no coincidirá ni con /user/ ni con /user
    router:get("/user/:name", function(params)
        local name = params["name"]
        ngx.print("Hola", name)
        ngx.exit(200)
    end)

    -- Sin embargo, este coincidirá con /user/john/ y también con /user/john/send
    -- Si no hay otros enrutadores que coincidan con /user/john, redirigirá a /user/john/
    router.get("/user/:name/*", function(params)
        local name = params("name")
        ngx.print("Hola", name)
        ngx.exit(200)
    end)

    -- Este coincidirá con /user/jhon/send.html, también coincidirá con cualquier uri que comience con /user/jhon/ y termine con .html
    router:get("/user/jhon/*.html", function(params)
        ngx.print("Hola")
        ngx.exit(200)
    end)

    router:run()

handler

El tipo de parámetro handler debe ser función o cadena, cuando el tipo es:

  • función, el manejador se llamaría cuando la uri coincida
  • cadena, el enrutador requeriría a.b, cuando el tipo de retorno es tabla, busca el método handle, si el tipo de retorno es función, la función de retorno se llamaría.

Consejos

  • La regla '*' se puede usar al final de la ruta
  • lanzar código http 500 cuando hay conflictos de ruta

run

El método run buscaría la ruta y llamaría al manejador. cuando no se encontró un manejador y se estableció notfound_handler, llamaría al manejador.

    local R = require("resty.router")
    local router = R:new()
    router:run() -- o router:run(notfound_handler)

Limitaciones

  • Esta biblioteca no se puede usar en contextos de código como set_by_lua*, log_by_lua*, y header_filter_by_lua* donde la API de cosocket ngx_lua no está disponible.
  • La instancia del objeto resty.memcached no puede ser almacenada en una variable Lua a nivel de módulo Lua, porque entonces será compartida por todas las solicitudes concurrentes manejadas por el mismo proceso trabajador de nginx (ver http://wiki.nginx.org/HttpLuaModule#Data_Sharing_within_an_Nginx_Worker) y resultará en malas condiciones de carrera cuando las solicitudes concurrentes intenten usar la misma instancia de resty.memcached. Siempre debes iniciar objetos resty.memcached en variables locales de función o en la tabla ngx.ctx. Estos lugares tienen sus propias copias de datos para cada solicitud.

GitHub

Puedes encontrar consejos de configuración adicionales y documentación para este módulo en el repositorio de GitHub para nginx-module-router.