跳转到内容

HTTP 端点

端点 (http.endpoint) 定义执行 Lua 函数的 HTTP 路由处理器。

- name: get_user
kind: http.endpoint
meta:
router: app:api_router
method: GET
path: /users/{id}
func: app.users:get_user
字段类型必需说明
meta.routerregistry.ID父级路由器 (如果仅注册了一个路由器则默认使用该路由器)
methodstringHTTP 方法
pathstringURL 路径模式
funcregistry.ID要执行的函数

支持的方法:

方法用途
GET获取资源
POST创建资源
PUT替换资源
PATCH部分更新
DELETE删除资源
HEAD仅获取头部
OPTIONSCORS 预检 (自动处理)
TRACE诊断回环

使用 {param} 语法定义 URL 参数:

- name: get_user
kind: http.endpoint
method: GET
path: /users/{id}
func: get_user
- name: get_user_post
kind: http.endpoint
method: GET
path: /users/{user_id}/posts/{post_id}
func: get_user_post

在处理器中访问:

local http = require("http")
local function handler()
local req = http.request()
local user_id = req:param("id")
local post_id = req:param("post_id")
end

使用 {path...} 捕获剩余路径:

- name: file_handler
kind: http.endpoint
method: GET
path: /files/{path...}
func: serve_file
local function handler()
local req = http.request()
local file_path = req:param("path")
-- /files/docs/readme.md -> path = "docs/readme.md"
end

端点函数从 http 模块获取请求和响应对象:

local http = require("http")
local json = require("json")
local function handler()
local req = http.request()
local res = http.response()
-- 读取请求
local body = req:body()
local user_id = req:param("id")
local page = req:query("page")
local auth = req:header("Authorization")
-- 处理
local user = get_user(user_id)
-- 写入响应
res:set_content_type(http.CONTENT.JSON)
res:set_status(http.STATUS.OK)
res:write_json(user)
end
return { handler = handler }
方法返回值说明
req:method()stringHTTP 方法
req:path()string请求路径
req:param(name)stringURL 参数
req:params()table所有路径参数
req:query(name)string查询参数
req:query_params()table所有查询参数
req:header(name)string请求头
req:body()string请求体
req:body_json()table, error解析 JSON 请求体
req:has_body()boolean检查是否存在请求体
req:content_type()string内容类型
req:content_length()number请求体大小 (字节)
req:host()string主机名
req:remote_addr()string客户端 IP 地址
req:accepts(type)boolean内容协商
req:is_content_type(type)boolean检查内容类型
req:stream()Stream以流形式读取请求体 (用于大文件)
req:parse_multipart(max?)table, error解析 multipart 表单
方法说明
res:set_status(code)设置 HTTP 状态码
res:set_header(name, value)设置响应头
res:set_content_type(type)设置内容类型
res:write(data)写入原始响应体
res:write_json(data)写入 JSON 响应
res:write_event(data)发送 SSE 事件
res:set_transfer(encoding)设置传输模式 (SSE, chunked)
res:flush()将响应刷新到客户端

JSON API 的常见模式:

local http = require("http")
local function handler()
local req = http.request()
local res = http.response()
local data, err = req:body_json()
if err then
res:set_status(http.STATUS.BAD_REQUEST)
res:write_json({error = "Invalid JSON"})
return
end
local result = process(data)
res:set_status(http.STATUS.OK)
res:write_json(result)
end
return { handler = handler }
local http = require("http")
local function api_error(res, status, code, message)
res:set_status(status)
res:write_json({
error = {
code = code,
message = message
}
})
end
local function handler()
local req = http.request()
local res = http.response()
local user_id = req:param("id")
local user, err = db.get_user(user_id)
if err then
if errors.is(err, errors.NOT_FOUND) then
return api_error(res, http.STATUS.NOT_FOUND, "USER_NOT_FOUND", "User not found")
end
return api_error(res, http.STATUS.INTERNAL_ERROR, "INTERNAL_ERROR", "Server error")
end
res:set_status(http.STATUS.OK)
res:write_json(user)
end
return { handler = handler }
entries:
- name: users_router
kind: http.router
prefix: /api/users
middleware:
- cors
- compress
- name: list_users
kind: http.endpoint
meta:
router: users_router
method: GET
path: /
func: app.users:list
- name: get_user
kind: http.endpoint
meta:
router: users_router
method: GET
path: /{id}
func: app.users:get
- name: create_user
kind: http.endpoint
meta:
router: users_router
method: POST
path: /
func: app.users:create
- name: update_user
kind: http.endpoint
meta:
router: users_router
method: PUT
path: /{id}
func: app.users:update
- name: delete_user
kind: http.endpoint
meta:
router: users_router
method: DELETE
path: /{id}
func: app.users:delete
- name: admin_endpoint
kind: http.endpoint
meta:
router: admin_router
method: POST
path: /settings
func: app.admin:update_settings
post_middleware:
- endpoint_firewall
post_options:
endpoint_firewall.action: "admin"