API calls

From Halon, SMTP software for hosting providers
Revision as of 08:26, 18 December 2015 by Erik (talk | contribs) (Query external sources using REST)
Jump to: navigation, search

One of the Halon email gateway's most powerful features is the scripting language, which enables you tailor and integrate the system to perfection.

Query external sources using REST

The combination of json_decode(), http() and the cache's update_function allows us to create very fast and resilient API call functions. The example below uses a normal (short) cache for performance, and a "long term" cache for resilience, in case the API is down. It uses the rate() function to determine if the API takes too long to answer, in order to ensure high performance even if the API is slow. If more than 10 requests during the last 5 minutes took more than 1 second to finish, or it fails to verify the response with is_array(), the value in the long-term cache is returned instead. In other words; the code below assumes that the result is always a JSON array.

Include file
// Wrapper function, manages the short- and long-term caches
function api_call($query$args) {
$data cache ["ttl_function" => api_call_ttl"size" => 100000"update_function" => api_call_update api_call_http($query$args);

// The actual API call function
function api_call_http($query$args) {
$apiurl "http://api.example.com/halon?api-key=Zu97uDyS9QeufBId";
$httpoption = ["timeout" => 5];
// Bail out if the API is considered too slow
if (rate("api_call_http"serial(), 0300) >= 10)
$t1 executiontime();
// Perform the actual API call
$ret http($apiurl.$query$httpoption$args);
// Measure the API response time
$time executiontime() - $t1;
    if (
$time 1)
rate("api_call_http"serial(), 10300);

// Cache helper function, referenced in api_call()
function api_call_update($old$new) {
// Update the long-term cache and return the new value, if the response is valid...
if (is_array($new))
// Otherwise use the old value from the long-term cache
cache [] syslog("crit""api_call: Invalid response, using long-term cache");

// Cache helper function, referenced in api_call()
function api_call_ttl($result) {
// Set the short-term cache TTL to 1 hour, if the response is valid
if (!is_array($result))

Below is an example of how the api_call() function can be used; as domain-based routing in the pre-delivery context:

include "file:X";
if (
$transportid == "mailtransport:1") {
// Should use API routing
$route api_call("&type=route&recipientdomain=$1", [$recipientdomain]);
    if (!isset(
Reschedule(3600, ["reason" => "No route""increment_retry" => false]);
SetDestination($route["dest"], number($route["port"]));
    if (
SetSASL($route["sasl_user"], $route["sasl_pass"]);