lua-resty-rax

OpenResty 高性能路由器

$ opm get xiangnanscu/lua-resty-rax

lua-resty-rax

OpenResty 高性能路由器,专注于将字符串映射到处理器。

概要

    local Radix = require("resty.rax")
    -- make a rx instance with initial routes
    local rx = Radix.new({
      { path = { "/user/:name/age/#age" }, handler = "/user/:name/age/#age", method = { 'GET', 'POST' } },
      { path = { "/user/:name" },          handler = "/user/:name" }
    })
    -- insert a route
    rx:insert("/hello", { handler = "/hello", method = 'GET' })
    -- test matching
    ngx.say(rx:match("/hello"))
    ngx.say(rx:match("/user/xiangnan"))
    local data, matched = rx:match("/user/xiangnan/age/22", "GET")
    ngx.say(data, ':', matched.name, ':', matched.age)
    ngx.say(rx:match("/user/xiangnan/age/22", "PUT"))
    ngx.say(rx:match("/user/xiangnan/age/not_matched", "GET"))

输出

    nilfailed to match
    /user/:name
    /user/:name/age/#age:xiangnan:22
    nilfailed to match
    nilfailed to match

API

Radix.new

创建路由器

    ---@param routes? {path: string|string[], handler: any,  method?: string|string[]}[]
    ---@return Radix
    function Radix.new(routes)
    end

示例

    local rx = Radix.new()
    local rx = Radix.new({
      { path = { "/user/:name/age/#age" }, handler = "/user/:name/age/#age", method = { 'GET', 'POST' } },
      { path = { "/user/:name" },          handler = "/user/:name" }
    })

Radix.insert

插入路由。path 可以是静态字符串,或参数字符串,例如 /:foo(匹配 rfc1738 字符串)、/#id(匹配数字字符串)或 /prefix/*all(匹配任何包含 / 的字符串)。当未提供 method 时,表示此路由匹配任何方法。

    ---@param self Radix
    ---@param path string
    ---@param route {handler: any,  method?: string|string[]}
    ---@return boolean
    function Radix.insert(self, path, route)
    end

示例

    rx:insert("/foo", { handler = "foo" })
    rx:insert("/bar", { handler = function(request) return "bar" end, method = 'GET' })
    rx:insert("/baz", { handler = "baz", method = { "get", "post" } })
    rx:insert("/number/#id", { handler = "/number/#id" })
    rx:insert("/prefix/*", { handler = "/prefix/*" })
    rx:insert("/another*", { handler = "/another*" })
    rx:insert("/named_prefix/*pname", { handler = "/named_prefix/*pname" })

Radix.match

从字符串匹配路由。如果未提供 method 且路由是使用 method 创建的,即使 path 匹配,匹配也会失败。如果匹配到静态路由,则返回路由中定义的处理器。如果匹配到动态路由,则返回处理器和匹配表。

    ---@param self Radix
    ---@param path string
    ---@param method? string
    ---@return any, (string|table)?, number?
    function Radix.match(self, path, method)
    end

示例

    rx:match("/fooo")         --fail
    rx:match("/foo")          --ok
    rx:match("/foo", "GET")   --ok
    rx:match("/foo", "post")  --ok
    rx:match("/bar", "GET")   --ok
    rx:match("/bar", "post")  --fail
    rx:match("/baz", "GET")   --ok
    rx:match("/baz", "post")  --ok
    rx:match("/bar", "patch") --fail
    local handler, matched = rx:match("/number/5") -- ok, handler = "/number/#id", matched = {id = 5}
    rx:match("/number/foo") -- fail, foo is not number

安装

    bash -c "$(curl -fsSL https://raw.githubusercontent.com/xiangnanscu/lua-resty-rax/main/install.sh)"

以上命令假设您将 OpenResty 安装在 /usr/local/openresty 中,实际上其内容是

    cd /tmp
    rm -rf lua-resty-rax
    git clone https://github.com/xiangnanscu/lua-resty-rax.git --depth=1
    cd lua-resty-rax
    make && INST_PREFIX=/usr/local/openresty make install && make clean

作者

Nan Xiang(@xiangnanscu)

许可证

Apache 2.0

版本