HTTP routing

Пример

  1. Допустим мы имеем фрамент с именем 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!"
  1. Добавим 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"

  1. Добавленные обработчики доступны по пути /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!
  1. Смотрим лог фрагмента:
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)