We have a client that runs a Drupal 7 site. They wanted to integrate a custom JSON API into the Drupal site. There’s already a great post covering a simple read only API endpoint in Drupal 7. I wanted to discuss both some points about API integration in general and cover receiving JSON data into Drupal and taking actions based on the input.
When you are using Drupal, think about what your source of record will be. If you can pick one system to hold all the data for the particular operation, things will be simpler than if you spread data between Drupal and the external API. Of course, Drupal isn’t totally stateless. We found it worked best if Drupal held “Drupal stuff” like users and permissions and kept other data in the API system. You can also leverage Drupal’s strengths, like the intuitive user management and powerrful permissions system, to control access to the API functionality. Or even, if you choose to make permissions more granular, to parts of the API; you could choose to have a different permissions to read from and write to the API.
Here’s an example of how to consume an API call. We’re expecting JSON to be posted to the endpoint. First, add an item to hook_menu to receive the call:
$items["/path/to/api"] = array(
'page callback' => 'api_method',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
Note that the ‘access callback’ argument is TRUE, because we are going to authenticate and authorize the API without using Drupal. Then we want to process the JSON using our page callback method:
function api_method() {
$expected_token = variable_get('api_token_var');
$received_token = $_SERVER["HTTP_TOKEN"];
if ($received_token != $expected_token) {
drupal_add_http_header('Status', '403 Not Authorized');
echo "";
return;
}
$received_json = file_get_contents("php://input", TRUE);
$status = "ok";
$message = "";
$json_valid = _api_validate_json($received_json);
if ($json_valid) {
// process your json object.
} else { drupal_add_http_header(‘Status’, ‘400 Bad Request’); echo “”; return; }
return drupal_json_output(array(“status” => $status, “message” => $message));
}
First we look to see if this is a valid API call. We check for a token to be passed along (so we need to make sure this is sent over SSL). Note that for this API the token is just a general variable, but you could have multiple tokens if you needed. If the token isn’t the expected value, we return a ‘not authorized’ status code. This is using the special ‘Status’ header, which causes Drupal to send an HTTP response code.
Then we get the input JSON and parse it to make sure it is what we expect. If not, we respond with a different status code. If it is, we process the json object, calling into whatever Drupal functionality we need. In this case, we are looking up a user and sending them a message, but you could add a message to a queue or do any other required processing of the message. Finally we return a status and message if the operation succeeds.
Integrating with an external API, whether custom or standard, can extend the functionality of your Drupal CMS and provide a clean separation of concerns between business logic and user data.