# HTTP Request

Process

Performs an HTTP request to an external service when triggered. Supports GET, POST, PUT, DELETE, and PATCH. URL, headers, and body can be static (config) or dynamic (input).

HTTP Request
T
U
H
B
S
R
RH
OK
BY

# Inputs

IDAbbrevNameTypeDefaultDescription
triggerTTriggerBOOLEANfalseRising edge fires the HTTP request. Ignored while a request is in flight.
urlUURLSTRINGDynamic request URL. Overrides the URL config when non-empty.
headersHHeadersSTRINGDynamic headers as Key:Value pairs separated by |. Overrides config when non-empty.
bodyBBodySTRINGDynamic request body. Overrides the body config when non-empty.

# Outputs

IDAbbrevNameTypeDefaultDescription
statusSStatusNUMBER0HTTP status code of the last response. 0 means no request has been made yet.
responseRResponseSTRINGResponse body text from the last request.
response_headersRHResponse headersSTRINGResponse headers serialized as a JSON object string.
successOKSuccessBOOLEANfalseTrue if the last response status was in the 2xx range (200-299).
busyBYBusyBOOLEANfalseTrue while a request is in flight. Trigger is ignored while busy.

# Configuration

IDNameTypeDefaultUnitDescription
methodMethodENUM0HTTP method to use for the request.

Details:

Values: GET, POST, PUT, DELETE, PATCH
urlURLSTRINGStatic request URL. Used when the URL input is empty.
headersHeadersSTRINGStatic headers as Key:Value pairs separated by |. Used when headers input is empty.
bodyBodySTRINGStatic request body. Used when the body input is empty.

# State

IDNameTypeDefaultUnitDescription
prev_triggerPrevious triggerBOOLEANfalsePrevious trigger value for rising edge detection.
in_flightIn flightBOOLEANfalseTrue while waiting for an HTTP response.
request_startedrequest_startedNUMBER0

# Source Code

View Volang source
fn apply_headers(client, headers) {
    if (headers == "") {
        return
    }

    pairs = str::split(headers, "|")
    while (str::split_has_next(pairs)) {
        pair = str::split_next(pairs)
        kv = str::split(pair, ":")
        key = str::split_next(kv)
        value = ""
        while (str::split_has_next(kv)) {
            if (value != "") {
                value = str::fmt("{}:{}", value, str::split_next(kv))
            } else {
                value = str::split_next(kv)
            }
        }
        http::set_header(client, key, value)
    }
}

fn serialize_headers(m) {
    keys = map::keys(m)
    if (array::len(keys) == 0) {
        return "{}"
    }

    result = ""
    i = 0
    while (i < array::len(keys)) {
        key = array::get_at(keys, i)
        val = map::get(m, key)
        result = str::fmt("""{}"{}":"{}",""", result, key, val)
        i = i + 1
    }
    return str::replace(str::fmt("{{}}", result), ",}", "}")
}

fn get_method_string(method_index) {
    if (method_index == 0) { return "GET" }
    if (method_index == 1) { return "POST" }
    if (method_index == 2) { return "PUT" }
    if (method_index == 3) { return "DELETE" }
    return "PATCH"
}

fn do_request() {
    state::set("in_flight", true)
    state::set("request_started", time::uptime())
    output::set("busy", true)

    url = input::get("url")
    if (url == "") {
        url = config::get("url")
    }

    headers = input::get("headers")
    if (headers == "") {
        headers = config::get("headers")
    }

    body = input::get("body")
    if (body == "") {
        body = config::get("body")
    }

    client = http::client()
    http::set_method(client, get_method_string(config::get("method")))
    apply_headers(client, headers)

    if (body != "") {
        http::set_body(client, body)
    }

    http::call(client, url)
}

extern fn http::on_response(status, body, headers) {
    output::set("status", status)
    output::set("response", body)
    output::set("success", status >= 200 and status < 300)

    output::set("response_headers", serialize_headers(headers))

    state::set("in_flight", false)
    output::set("busy", false)
}

channel = input::channel()
value = input::value()

if (channel == "trigger") {
    if (state::get("in_flight")) {
        request_started = state::get("request_started")
        if (time::uptime() - request_started > 10000) {
            state::set("in_flight", false)
            output::set("busy", false)
            output::set("success", false)
        }
    }

    prev_trigger = state::get("prev_trigger")

    if (value and !prev_trigger) {
        if (!state::get("in_flight")) {
            do_request()
        }
    }

    state::set("prev_trigger", value)
}
Performs an HTTP request to an external service when triggered. Supports GET, POST, PUT, DELETE, and PATCH. URL, headers, and body can be static (config) or dynamic (input).