Consuming Drupal JSON Web Services with an API Key
Recently we had to integrate one of our Drupal sites with an iPhone application. A 3rd party was developing the iPhone application so basically we just had to provide the API and give some examples on how to talk to our Drupal site.
'No Problem!' I thought. We could simply use the services module. We did it several times before using the XMLRPC interface that comes with the services module.
JSON, For the Win!
We learned that using the XMLRPC flavor of web services isn't ideal for mobile access applications, because of it's verboseness. Basically, that means all the XML tags used to give structure to the actual data eats a lot of unecessary bandwidth. It turns out the JSON interface is a lot more economical.
Prerequisites
As a client consuming the web service, it's assumed that you already have the following prerequisites set up:
- A Drupal user account (username & password) with a role that has access permissions to the web services.
- The API key that was created in the system (Site Building > Services > Keys)
-
Your web services is configured (Site Building > Services > Settings) to
a) Use the 'Key Authentication' Authentication module.
b) Use keys is checked, and
c) Use sessid is checked.
In a nutshell...
With those in hand, the basic conversation goes like:
Broken down...
What do these requests actually look like? They're actually just POST requests made to your Drupal sites' /services/json-rpc URL, with 2 query parameters: method
and params
.
system.connect
Actually, I lied, the system.connect service is the only one that just takes one query parameter, the 'method'. Send a POST request to /services/json-rpc and you'll get a SESSION_ID in return. Save that for the user.login service call coming next.
Access: GRANTED
After you successfully call the user.login service, Drupal will return to you a new SESSION_ID. Save your new SESSION_ID, and call subsequent web services the same way as the user.login request, but using the new SESSION_ID.
For example, a node.get request would look like:
method = node.get
params = {
hash: '$hash',
domain_name: '$domain_name',
domain_time_stamp: $domain_time_stamp,
nonce: '$nonce',
sessid: '$authenticated_session_id',
nid: $nid
}
Hope this helps!