Adding an API to your Drupal site doesn’t have to be difficult, well…not too difficult. Using the Services module removes a lot of the work needed and sets you up for an easy implementation. Its especially nice with its hooks and it outputs everything in json format and handles error messaging.
I won’t get into the admin/UI side of the Services module, but this is the code to create a new REST server for the Services module.
This will be an open API with no authentication, but I’ll throw in a permission in there just in case we want to limit this later to a certain user role. Once again, this is just a basic code example.
/**
* Implements hook_permission().
*/
function mymodule_permission() {
return array(
'mymodule get nodes' => array(
'title' => t('Get nodes via mymodule REST API'),
),
);
}
/**
* Implements hook_services_resources().
*/
function mymodule_services_resources() {
return array(
'get_nodes' => array(
'index' => array( // 'index' is used when no parameters are passed using GET
'help' => 'Retrieves drupal nodes',
'callback' => '_mymodule_get_nodes',
'access callback' => '_mymodule_access',
'access arguments' => array('index', 'node'),
'access arguments append' => FALSE,
),
),
'retrieve' => array( // 'retrieve' is used when a parameter is passed using GET
'help' => 'Retrieves a specific node',
'callback' => '_mymodule_get_node',
'args' => array(
array(
'name' => 'nid',
'optional' => FALSE,
'source' => array('path' => 0),
'type' => 'int',
'description' => t('The node nid to retrieve.'),
),
),
'access callback' => '_mymodule_access',
'access arguments' => array('view', 'node'),
'access arguments append' => FALSE,
),
/*
* some other additional methods are
* 'create' => POST
* 'update' => PUT
* 'delete' => DELETE
*/
);
}
/**
* Access callback function.
*/
function _mymodule_access($op = 'view', $type, $args = array()) {
switch ($op) {
case 'index':
case 'view':
if ($type == 'node' && user_access('mymodule get nodes')) {
return TRUE;
}
break;
}
}
/**
* index callback function.
*/
function _mymodule_get_nodes() {
$items = array();
$query = db_select('node', 'n');
$query->fields('n', array('nid', 'title'));
$query->orderBy('n.title', 'ASC');
$results = $query->execute()->fetchAll();
foreach ($results as $r) {
$item[] = array(
'nid' => $r->nid,
'title' => $r->title,
);
}
if (!count($items)) {
return services_error('no nodes found, 404);
}
return $items;
}
/**
* retreive callback function.
*/
function _mymodule_get_node($nid) {
if (is_numeric($nid)) {
$node = node_load($nid);
if ($node->nid) {
$item = array(
'nid' => $node->nid,
'title' => $node->title,
);
return $item;
}
}
return services_error('node not found, 404);
}
This is about as short as I can get it. You should do additional security checks and basic validation, but you get the idea 🙂
It would also be great to add a way of limiting the ‘index’ by adding parameters/arguments, since it could get crazy to return ALL nodes of your site
www.mysite.com/api/get_nodes?start=150&count=100
Good Luck!