HTTP routing¶
Пример¶
- Допустим мы имеем фрамент с именем
fr1.lua
в снапшотеTestSnapshot
с тегомdev
. Код фрагмента:
local ap = require 'ap' print(ap.args.arg1) print(ap.args.argument_2) print(ap.args.arg3) print(ap.args.myHeaderArgument) return "Hello World!"
- Добавим HTTP-обработчик через вызов метода:
curl -X POST -H "Content-Type: application/json" \ -d "@handler_meta.json" \ http://dn5.isa.ru:5678/http/handlers/register
handler_meta.json
:
[ { "active": true, "httpMethod": "POST", "pathPattern": "/my/complex/{arg1}/path/{arg2}", "arguments": [ { "name": "arg1", "placement": "Path" }, { "name": "arg2", "placement": "Path", "alias": "argument_2" }, { "name": "arg3", "placement": "Query", "optional": true }, { "name": "My-Header", "placement": "Header", "alias": "myHeaderArgument" } ], "handler": { "fragment": "Alex/TestSnapshot/dev:fr1.lua", "transactionId": "123", "logging": { "redirections": { "stdout": { "id": "log", "scope": "FRAGMENT" } } } } } ]
Аргументы HTTP-обработчика имеют имя (name
), оно трактуется по разному в зависимости от местоположения аргумента (placement
):
если placement == Path
, то имя аргумента это имя аргумента внутри шаблона (pathPattern
)
если placement == Query
, то имя аргумента это имя параметра в query или form
если placement == Header
, то имя аргумента это имя загаловка
если placement == Body
, то имя аргумента игнорируется про разборе HTTP-запроса, но оно все равно необходимо,
т.к. словарь аргументов фрагмента ap.args
заполняется по именам аргументов (если не указан alias
)
Аргументы HTTP-обработчика добавляются в словарь аргументов фрагмента ap.args
по псевдониму (alias
) или, если он не указан, по имени (name
).
При этом существующие аргументы с таким же именем перезаписывются.
По умолчанию, все аргументы HTTP-обработчика обязательны. Сделать аргумент необязательным можно указав свойство "optional": true
Query-параметры могут быть положены как form-параметры в body, для этого необходимо установить "Content-Type": "application/x-www-form-urlencoded"
- Добавленные обработчики доступны по пути
/io/<username>
. Тестируем:
curl -X POST -H "My-Header: XYZ" http://dn5.isa.ru:5678/io/Alex/my/complex/p1/path/p2?arg3=p3
->
Hello World!
- Смотрим лог фрагмента:
curl -X GET http://dn5.isa.ru:5678/vm/transactions/123/frlogs/log/fragments/fr1.lua
->
p1 p2 p3 XYZ
Кастомизация HTTP-ответа¶
В API фрагмента доступен метод ap.http.respond
, который действует аналогично ap.commit
, т.е. бросает специальное исключение (его нельзя опознать в lua).
local ap = require 'ap' local headers = { ["Any-String"] = "ABC", ["My-Header"] = "XYZ" } local body = "hello world!" return ap.http.respond(400, body, headers)