Over the last few weeks, there’s been a bit of excitement in the world of Church Community Builder, also affectionately known as CCB.

I use “excitement” loosely as many churches using CCB’s API were informed about CCB implementing a new per-minute rate limiting policy in addition to its per-day allotment of 10,000 calls per day — which they hope to retire sooner rather than later, yet it’ll remain in place for now.

As of August 20th, this new rate limiting strategy aims to restrict how many times per minute an API user can access an individual API Service — noted in New API Rate Limiting documentation.

So, what does this truly mean to you, and more importantly, how does this new strategy impact developed applications and environments using CCB’s API? 🤔

In short, rate limiting is not a bad thing. Rate limiting truly aims for the following:

  • Provide greater data security controls in event of a data breach
  • Protect APIs from overuse by limiting how often each user can call the API
  • Reduce, if not eliminate, the opportunity from inadvertent and malicious overuse that may lead to API request spiking

There are likely other benefits from rate limiting, but these are simply a few that come to mind.

Who and what might this new change impact the most?

Churches having developed multi-threaded or multi-processing scripts to get or post data to and from CCB using the API are greatly impacted by this new policy.

If you don’t use multi-threaded processes, then this new change is less likely to impact your church. But don’t think you’re in the clear just yet.

If your church performs any of the following tasks, to name just a few that come to mind, then it’s recommended to review, adjust and adhere to the CCB’s API rate limiting policy:

  • Batching of any sort
  • Nightly attendance reporting
  • Nightly or incremental backups
  • Custom community group applications
  • Mobile applications

No matter if single or multi-thread development, you’re likely going to notice and realized hampered performance for development efforts simultaneously and consecutively requesting multiple API Services.

What actions should be taken to comply?

If an API user chooses to take no action regarding the new api rate limiting policy, then you’re likely going to run afoul and have your API access temporarily or permanently revoked for your church’s subdomain.

As stated in the API rate-limiting documentation, CCB is now provides HTTP Headers and Response Codes. Plan accordingly to have logic implemented within your software or application that takes into account rate-limiting attributes and their respective limits (see documentation).

Code Example of Logic to Incorporate API Rate-Limit Headers

To prepare for the new rate limiting restrictions per documentation, CCB has provided a rate_limit_test API Service to test the rate limiting service without penalty.

Nevertheless, if you’re using code from this website, then a few modifications to the general.php file are needed to incorporate the appropriate API rate-limit logic.

If Using Windows

If you’re using PHP in a Windows environment, then you’ll need to ensure the following is added to the general.php file in the cURL transfer setup options of the ccbDetails function.

<?PHP

// Windows section of ccbDetails function
// set to 1 or true to retrieve headers
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_NOBODY, 1);


?>

The above curl_setopt options of CURLOPT_HEADER and CURLOPT_NOBODY ensure HTTP Headers and Response Codes are returned.

If Using *nix

If you’re using PHP in a Unix or Linux environment, then you’ll need to ensure the following is added to the *nix section of the ccbDetails function in the general.php.

<?PHP

// NON WINDOWS Section of ccbDetails function in general.php
// time to make PHP/CURL call using shell_exec command and CCB API curl
$output = shell_exec('curl -k -u '.$apiUsername.':'.$apiPassword.' -d "'.$objData.'" -i "'.$url.'"');

?>

Add “-i” to the executed curl command using shell_exec ensure HTTP Headers and Response Codes are returned.

The last change to be made in the general.php file occurs before returning the transformed XML using PHP’s built-in SimpleXMLElement method. The code looks as follows:

<?PHP

// output then let's start additional logic to parse and display output to web browser; if not output response, then error and die.
if($output){

$response_object = ''; // reset $response_object

$response_object = new SimpleXMLElement($output); // transform to XML

//echo $response_object;
 
} else {

    $response_object = 'WINDOWS Error: curl_exec() command failed.';
    if($devEnv != 'WIN')
        $response_object = 'LINUX Error: shell_exec() command failed.';

    die($response_object);

}


?>

In between the $response_object variables, add the following code (read comments for explanation):

<?PHP

// output then let's start additional logic to parse and display output to web browser; if not output response, then error and die.
if($output){

$response_object = ''; // reset $response_object

// separate the response into header and body sections respectively
$data = explode("\r\n\r\n",$output);

// header section: create array of each header line
$headerData = explode("\n",$data[0]);

// remove the first array containing a header response
array_shift($headerData);

// iterate over each line and separate each header into header key adn header value pairs
foreach ($headerData as $k=>$v){    
    $v=explode(': ', $v, 2);
    $responseHeaders[$v[0]]=$v[1];
}

// use the following four comments lines to debug / test - simply remving "//" at the beginning of each line when testing and debugging
//echo '<pre>';
//print_r($responseHeaders);
//echo '<pre>';
//die();

// the following logic allows the code to sleep for a certain amount of seconds that comply to rate-limit attributes
if($responseHeaders["Retry-After"] > 0) {

    sleep($headers["Retry-After"]);

} else if($responseHeaders["X-RateLimit-Remaining"] /

    $responseHeaders["X-RateLimit-Limit"] < 0.25) {

    sleep($responseHeaders["X-RateLimit-Reset"] - time());

}

$output = $data[1];

$response_object = new SimpleXMLElement($output); // transform to XML

//echo $response_object;
 
} else {

    $response_object = 'WINDOWS Error: curl_exec() command failed.';
    if($devEnv != 'WIN')
        $response_object = 'LINUX Error: shell_exec() command failed.';

    die($response_object);

}

?>

Special hat tip to Jon Diercks for proposed logic and solution using the HTTP Headers.

If desired, you could also return the headers with the XML response as an array, and then access the headers in your script should you make additional API calls.

This could come in handy for scripts that iterate using for or foreach loops.

In closing, the good news is that you have from now until August 20th to figure out the appropriate action to take for your various CCB API development efforts.

And it goes without saying, but certainly feel free to contact us should you need assistance assessing a plan of action for your CCB API development efforts.

Thanks and that’s all for now!

Related Posts

Subscribe and receive the following...

  • Inside CCB tips and tricks
  • Instant CCB tutorial alerts and updates
  • CCB How To's, Videos, Webinars and more...