Your Drupal Site API
As IT citizens, we are often pictured while glued to our monitors doing whatever we need to do to keep software humming on servers or porting applications from legacy technologies to more up-to-date software stack or trying to figure out why things work one way on environment Y while when the exact same code deployed in environment X the app just decides to stall. Well, I think you know what I mean: we spend countless hours hunched in front of our monitors neglecting that we need to also hum that vital organ in our chests to maintain our own health and a decent fitness level. In an effort to promote health and fitness at Function1, during our last quarterly meeting, our CEO handed each one us a Fitbit devise that monitors and logs our physical activity during the course of the day. The cool part is that through a custom built Ruby on Rails app, we were seeing each other’s progress on a dashboard displaying our daily and monthly steps count and where we stack with one another (which I thought was pretty fun as we kept encouraging each other.) Now, Fitbit as a company is smart; it doesn’t just sell us a piece of gadget tied to our wrist, it also exposes what it stores about the registered users (our tracker collection and statistical data) and through its RESTful APIs and OAuth authorization it allows client apps developed in PHP, Ruby, .Net, etc. to read that data and display it in whatever format or layout on some third party app. Fitbit isn’t the only company that exposes its data store through APIs, some of the most commonly used APIs on the web are Twitter, Netflix, Dropbox, weather services, etc.
Now back to our own realm: Drupal. Drupal stores tons of data about nodes, taxonomies, comments, blogs, users, etc. and porting the Fitbit API model in the Drupal world would allow an arbitrary client, a third party application, or some piece of code (through proper authentication) to interact with the Drupal site. That brings us to the Drupal Services module. However, unlike the Fitbit API which is a set of direct RESTful calls which permit that tapping to the Fitbit data, the Drupal Services modules is an intermediary layer on top of Drupal that enables us to create our own set of REST or SOAP based web services that would then tap into our Drupal data store. The power of the Drupal services module is that it understands the intricacies of the Drupal data structure and data types; it knows what is a node and what is a published and not published content item and returns that data in a standard and structured format; e.g. JSON, XML. So through the Drupal Services module we can then expose our own set of services APIs whether REST or XML based.
After installing the Drupal Services module, creating a new web service, defining its endpoint and path, defining its server type (REST or SOAP), defining the response formatters (JSON, XML, or both), defining the request parsing type (application/json, application/xml, multipart/form-data, etc.) we will need to define what are the Drupal resources we want to expose and the operations we want to allow; and that is the bread and butter of our API. The figure below is from the “Resources” tab in the service module under the web service we just created and it lists the types of resources that can be exposed.
Once we select what resource(s) will get exposed, we’ll need to define the CRUD operations that will be permitted for each resource. This is illustrated below for a resource of type "node".
But along with defining what resource to fetch and what operations to allow, we can retrieve the "relationships" associated with that resource and that “relationships” listing would differ depending upon the parent resource type. So in essence we can retrieve a resource along with its entire properties bag.
To test the service, in the browser you can then navigate to <www.example.com>/<endpoint-name>/<resource-type>/<resource-id.json> thus retrieving that specific resource id in JSON format or something like <www.example.com>/<endpoint-name>/<resource-type.json> to retrieve all resources of that specific type (node in our case.) With either example, the returned JSON would include all properties associated with that resource; e.g. name, type, language, the user who create the node, publishing status, the body, etc.
But really no one wants a two-mile long JSON array of nodes to display on a web page, so we would need to pass some arguments or query parameters to the service to filter the returned resources on specific selection criteria. Now seriously, to locate that information on d.org is like searching for a needle among 2 million needles scattered in a haystack. Our best bet is to look straight at the code; so depending on which resource you are exposing and want to filter, look for that resource include file in docroot/sites/all/modules/services/resources/
Since we are filtering on nodes, open the node_resource.inc file (code snippet above) and locate the index array around line 82 and then under the parameters array line 103 (code snippet below) we’ll note that the service can take “parameters” as a query value and it is of type array. For example, if we were to list resources of types nodes that were not published and waiting for review, the REST call would be <example.com>/<endpoint-name>/resource-type>?parameters[status=0] and to further narrow down the filter on nodes of type “blog” we can do <example.com>/<endpoint-name>/resource-type>?parameters[status=0]¶meters[type]=blog. You still need to know that “status” and “type” are valid fields of a node and that “0” and “blog” are valid values for each field respectively but you would see these name/value pairs from the returned JSON or through the awesome devel module .
It is really up-to-you to decide what Drupal resources on your site you would want to expose and that, obviously, depends upon what the client/consuming application needs. But if you have a use case where you need to periodically send data exports of your nodes for subsequent import in some other app or perhaps exposing your latest and most visited blogs on a partner website in a block, then surfacing that data set through an API might be the way to go.
Happy API’ing
- Log in to post comments