콘텐츠로 이동

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진단 루프백

URL 파라미터에 {param} 구문 사용:

- 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, errorJSON 본문 파싱
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멀티파트 폼 파싱
메서드설명
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"