KDB knowledge

Calling web services from SQL (http_get, http_post)

http_get and http_post call a web address from SQL, a procedure or a timer. Off until an admin lists the hosts they may call.

http_get and http_post let SQL call another service. A procedure can tell a settlement service that a day is done. A timer can ask a checker every hour.

Example: On a server where nobody turned them on, a call is refused (shows an error)

SELECT http_get('http://10.0.0.5:8080/health');

Result:

Error: line 1, column 8: http_get: calling web addresses from SQL is off on this server; an admin turns it on by listing the hosts it may call in the setting http_functions (kdb.conf, KDB_HTTP_FUNCTIONS or the Settings page)

http_get

Syntax:

http_get(url)
http_get(url, headers)

Sends a GET request and waits for the whole answer.

ArgumentTypeMeaning
urltexthttp://host[:port]/path or https://....
headersJSON objectextra request headers, like '{"Authorization":"Bearer abc"}'. Optional.

http_post

Syntax:

http_post(url, body)
http_post(url, body, content_type)
http_post(url, body, content_type, headers)

Sends a POST request with a body.

ArgumentTypeMeaning
urltextas for http_get.
bodytext or JSONwhat to send.
content_typetextthe Content-Type. Default application/json for a JSON value, else text/plain; charset=utf-8.
headersJSON objectextra request headers. Optional.

Reading the answer

Use the JSON operators and functions on the result:

You wantWrite
the statusjson_value_long(r, '$.status')
the body as textr ->> 'body'
one headerr -> 'headers' ->> 'content-type'
a field of a JSON bodyjson(r ->> 'body') ->> 'ok'

A procedure that calls a service and keeps what it said (it runs once http_functions lists 10.0.0.5:8080):

CREATE TABLE settle_log (at TIMESTAMP, status INT, body STRING);

CREATE PROCEDURE settle_day() AS BEGIN
  INSERT INTO settle_log
  SELECT now(), json_value_long(r, '$.status'), r ->> 'body'
  FROM (SELECT http_post('http://10.0.0.5:8080/settle', json_object('day', current_date),
                         'application/json', '{"Authorization":"Bearer my-token"}') AS r) AS call;
END;

Turning them on

SettingWhereDefaultMeaning
http_functionskdb.conf, KDB_HTTP_FUNCTIONS, the Settings pageoffthe hosts SQL may call, separated by commas
http_timeout_mskdb.conf, KDB_HTTP_TIMEOUT_MS, the Settings page10000the most milliseconds one call may take, redirects included

kdb.conf wins over the environment. A save on the Settings page applies at once, without a restart.

How to write the list:

EntryAllows
api.example.comthat host, any port
10.0.0.5:8080that address, port 8080 only
*every host (still not 169.254.x.x, see below)
offnothing: the functions are off
{"http_functions": "settle.internal:8080, 10.0.0.5", "http_timeout_ms": 5000}

What a call may do

RuleWhy
http:// and https:// onlynothing else is a web service
https checks the certificate against the authorities the computer trustsso nobody in between can answer instead
at most 3 redirects, each to an allowed hosta redirect cannot lead out of the list
Authorization and Cookie are not sent on to another hosta token is for the host it was written for
169.254.x.x and 0.x.x.x are refused unless that host is listed by itselfclouds give out secret keys at 169.254.169.254
at most 16 MB of answera big answer is an error, never a cut body
IPv4 only

Who may call

CallerMay call
no login (a local tool, the server token)yes
a user with role write or adminyes
a user with role readno: "needs role write", also through a view
a procedure (CALL needs write), a trigger, a timeryes

The text of a statement goes to the activity log and the slow-query log. There, every argument after the address shows as '***', so a token in the headers is never kept.