Extending our RESTful API

This article will guide you through the steps of extending the SPBAS API to get all licenses for a customer using the e-mail address. However, the article can be used as a general guide to writing your own API calls.

You will need a text editor, SSH or FTP, SPBAS installed & configured and you must have a basic understanding of PHP, SPBAS and the logic behind RESTful API's. Let's begin.


Step 1: Obtain an API Key


The API key is used to authenticate the API request. It will always be 32 characters and should be kept private as a published key would allow anyone access to your API ( and as a result of that, your SPBAS data). Follow these steps to find your API key:


1. Login to SPBAS

2. Click Settings and then Setup

3. Click the m3 tab

4. Look for API Key: and make note of it, you'll need it for step 4.



Step 2: Configure Your Extension


You must now configure your API extension. We are going to do this in such a way that future upgrades won't destroy our work today. If you have extended the SPBAS API in the past you can skip this step. Otherwise, it's advisable to complete this step:


1. Open api/configuration.php

2. Add the following line to the bottom of the file (just above the ending ?>):

include 'my_extensions.php';

3. Save, but don't upload yet.


Now we need to make our my_extensions.php include. Here's a template you can use:
<?PHP
// Uncomment this if you are creating a whole new 
// API module (beyond the scope of this article, see related articles)
// $valid_mods[]='';

// For this example, we are going to extend the API 
// to get a customers license info by e-mail address.
$valid_tasks[]='get_license_info';
?>



Step 3: Write the API


Take note of line 8 ($valid_tasks[]='get_license_info';) in the configuration example above, "get_license_info" is our task name. Since this is an extension of the licensing module we'll add the task to the license module. To do that, follow the steps below:


1. Create a new task file:

api/modules/license/get_license_info.php

2. Open this file in your text editor.


You must validate the API key in every task file. Here's code to do that:
<?PHP @api::ran_directly();

// NOTE: $errors has already been set to an empty array().

// validate the incoming API key
if (!mod::validate_api_key(x('api_key'))) { $errors[]='Invalid API Key'; }
?>

Building on the above, let's make sure we have an e-mail address:
<?PHP @api::ran_directly();

// NOTE: $errors has already been set to an empty array().

// validate the incoming API key
if (!mod::validate_api_key(x('api_key'))) { $errors[]='Invalid API Key'; }

if (empty($errors))
	{
	// do we have a value posted on the key email?
	if (!x('email')) 
		{ 
		$errors[]='Missing the target e-mail address.'; 
		}
	}
?>

Now that all requirements are met, lets query the license data and add it to the $buffer stream:
<?PHP @api::ran_directly();

// NOTE: $errors has already been set to an empty array().

// validate the incoming API key
if (!mod::validate_api_key(x('api_key'))) { $errors[]='Invalid API Key'; }

if (empty($errors))
	{
	// do we have a value posted on the key email?
	if (!x('email')) 
		{ 
		$errors[]='Missing the target e-mail address.'; 
		}
	}

if (empty($errors))
	{
	// $buffer is a stream, attach things to it that are to
	// be returned by the API, like licenses in this case.
	$buffer['licenses']=array();

	// get all licenses for a customer based on the e-mail address sent in
	$query=mysql_query("SELECT `m3_licenses` . *
	FROM `m3_licenses` , `m3_users` , `m3_customers` , `m3_customers_jusers`
	WHERE `m3_users`.`email` = '".a(x('email'))."'
	AND `m3_users`.`id` = `m3_customers_jusers`.`user_id`
	AND `m3_customers_jusers`.`customer_id` = `m3_customers`.`id`
	AND `m3_licenses`.`customer_id` = `m3_customers_jusers`.`customer_id`
	ORDER BY `m3_users`.`email` ASC");
	while ($rs=mysql_fetch_assoc($query))
		{
		// were the logs requested too?
		if (x('include_logs'))
			{
			$rs['license_logs']=array();
			$query2=mysql_query("SELECT *
			FROM `m3_license_log`
			WHERE `license_key` = '".a($rs['license_key'])."'
			ORDER BY created ASC");
			while ($rs2=mysql_fetch_assoc($query2))
				{
				$rs['license_logs'][]=$rs2;
				}
			}

		$buffer['licenses'][]=$rs;
		}
	}
?>

Take note of the function a() in the SQL queries above as it is very important in regards to security. It will sanitize data going into the database. Data coming out of the database can be wrapped in sx() to reverse the sanitation of a() or s() to do the same only without htmlentites converted.


So now we should have a complete data set, but what if we don't? It's always a good idea to set an error message for things like this. So again, building on the code above, let's set an error message and finally add that error message to the $buffer stream:
<?PHP @api::ran_directly();

// NOTE: $errors has already been set to an empty array().

// validate the incoming API key
if (!mod::validate_api_key(x('api_key'))) { $errors[]='Invalid API Key'; }

if (empty($errors))
	{
	// do we have a value posted on the key email?
	if (!x('email')) 
		{ 
		$errors[]='Missing the target e-mail address.'; 
		}
	}

if (empty($errors))
	{
	// $buffer is a stream, attach things to it that are to
	// be returned by the API, like licenses in this case.
	$buffer['licenses']=array();

	// get all licenses for a customer based on the e-mail address sent in
	$query=mysql_query("SELECT `m3_licenses` . *
	FROM `m3_licenses` , `m3_users` , `m3_customers` , `m3_customers_jusers`
	WHERE `m3_users`.`email` = '".a(x('email'))."'
	AND `m3_users`.`id` = `m3_customers_jusers`.`user_id`
	AND `m3_customers_jusers`.`customer_id` = `m3_customers`.`id`
	AND `m3_licenses`.`customer_id` = `m3_customers_jusers`.`customer_id`
	ORDER BY `m3_users`.`email` ASC");
	while ($rs=mysql_fetch_assoc($query))
		{
		// were the logs requested too?
		if (x('include_logs'))
			{
			$rs['license_logs']=array();
			$query2=mysql_query("SELECT *
			FROM `m3_license_log`
			WHERE `license_key` = '".a($rs['license_key'])."'
			ORDER BY created ASC");
			while ($rs2=mysql_fetch_assoc($query2))
				{
				$rs['license_logs'][]=$rs2;
				}
			}

		$buffer['licenses'][]=$rs;
		}
	}

// set an error message if the e-mail address
// doesn't correspond to any licenses
if (empty($errors)&&!is_array($buffer['licenses']))
	{
	// always assign errors to an array
	$errors[]='No licenses found.';
	}

$buffer['errors']=$errors;
?>


Step 4: Uploading the API Extension


Now that you've configured your API extension and written the task it's time to go live with the changes for testing. To do that upload the following files:


- api/configuration.php
- api/my_extensions.php
- api/modules/license/get_license_info.php



Step 4: Accessing the API


So our adventure is nearly complete. We still need to test our work though. Use the code snippet below as a standalone file for testing. Later, after you've confirmed it's working, you can embed it into your script or use it where ever it's needed.

<?PHP
/**
* This file is included in the dev kit attached to this article.
*
* Please note! Never include api.php in your production code.
* Always embed it instead. Embed it into the file you want to
* protect or into one of your other very important files.
*
* If you include it, the end user can simply rewrite it.
*/
include_once 'api.php';

// the path to the SPBAS api/ directory
$api_handler='http://domain.com/spbas/api/index.php';

// your API Key from step 1
$api_key='';

// from step 3, we are using the license module
$mod='license';

// from step 3 again, enter the task name
$task='get_license_info';

// the API requirements
$data=array(
			'email'			=> '',	// the users e-mail address
			'include_logs'	=> 0	// set to 1 to get the logs too
			);

// query the API!
$request=api::query($api_handler, $api_key, $mod, $task, $data);

// examine the results
echo '
';
print_r($request);
echo '
'; ?>

Andy Rockwell

Print Article

Add Bookmark

REST_API_Dev_Kit.zip


Was this article helpful?

Yes, it was helpful.

No, it was not helpful.



Related Articles

Powered by SPBAS Business Automation Software