API calls

From Halon, SMTP software for hosting providers
Jump to: navigation, search

One of the most powerful features of the Halon SMTP software is the HSL 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);
    return 
$data;
}

// 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)
        return;
    
$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);
    return 
json_decode($ret);
}

// 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))
        return 
$new;
    
// Otherwise use the old value from the long-term cache
    
cache [] syslog("crit""api_call: Invalid response, using long-term cache");
    return 
$old;
}

// 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))
        return 
60;
    return 
3600;

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(
$route["dest"]))
        
Reschedule(3600, ["reason" => "No route""increment_retry" => false]);
    
SetDestination($route["dest"], number($route["port"]));
    if (
$route["sasl_user"])
        
SetSASL($route["sasl_user"], $route["sasl_pass"]);