# HTTP Request
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
| ID | Abbrev | Name | Type | Default | Description |
|---|---|---|---|---|---|
trigger | T | Trigger | BOOLEAN | false | Rising edge fires the HTTP request. Ignored while a request is in flight. |
url | U | URL | STRING | | Dynamic request URL. Overrides the URL config when non-empty. |
headers | H | Headers | STRING | | Dynamic headers as Key:Value pairs separated by |. Overrides config when non-empty. |
body | B | Body | STRING | | Dynamic request body. Overrides the body config when non-empty. |
# Outputs
| ID | Abbrev | Name | Type | Default | Description |
|---|---|---|---|---|---|
status | S | Status | NUMBER | 0 | HTTP status code of the last response. 0 means no request has been made yet. |
response | R | Response | STRING | | Response body text from the last request. |
response_headers | RH | Response headers | STRING | | Response headers serialized as a JSON object string. |
success | OK | Success | BOOLEAN | false | True if the last response status was in the 2xx range (200-299). |
busy | BY | Busy | BOOLEAN | false | True while a request is in flight. Trigger is ignored while busy. |
# Configuration
| ID | Name | Type | Default | Unit | Description |
|---|---|---|---|---|---|
method | Method | ENUM | 0 | HTTP method to use for the request. Details: Values: GET, POST, PUT, DELETE, PATCH | |
url | URL | STRING | | Static request URL. Used when the URL input is empty. | |
headers | Headers | STRING | | Static headers as Key:Value pairs separated by |. Used when headers input is empty. | |
body | Body | STRING | | Static request body. Used when the body input is empty. |
# State
| ID | Name | Type | Default | Unit | Description |
|---|---|---|---|---|---|
prev_trigger | Previous trigger | BOOLEAN | false | Previous trigger value for rising edge detection. | |
in_flight | In flight | BOOLEAN | false | True while waiting for an HTTP response. | |
request_started | request_started | NUMBER | 0 |
# 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)
}
