Four Kitchens
Insights

REST easy, part 4: The tax(onomy) man!

7 Min. ReadDevelopment

Welcome to the fourth edition of the REST Easy tutorial series for the RESTful module. In previous posts we created a basic node endpoint for our REST API with the help of the RESTful module. In our last post we used the EFQ powered filtering of the RESTful module to return specific results from our API.

In today’s post I’d like to show you how easy it is to add different types of entities to the API. Drupal 7 uses entities for expressing a great many objects used by the CMS. Nodes are entities, taxonomy terms are entities, and field collections are entities just to name just a few. We will first add a vocabulary to our Drupal site, populate it with a bit of data, add that custom taxonomy to our API as an endpoint, and then finally make a GET request against our API to return JSON data from that endpoint.

A taxonomy to remember

As with all of these tutorials you can follow along below and build upon the work you’ve completed in lesson 1-3 or grab the code at the corresponding tag to this lesson from github Rest Easy (which will have features for the node and taxonomy and the API up until this point). This tutorial will assume you have done one or the other of these and have the necessary files for your API.

The first step in realizing a taxonomy endpoint in our API is to add a taxonomy vocabulary to our Drupal site.

Step 1: Add the vocabulary

Add the vocabulary below to your Drupal site:

/admin/structure/taxonomy/add
  • Name: Genre
  • Machine-readable name: taxonomy_genre
  • Description: Musical Genres

Step 2: Ensure permissions and add content

Let’s ensure we have the right permissions. Set the edit and delete permissions for your new taxonomy below to:

/admin/people/permissions

Let’s add some genres to this taxonomy to help us for the purposes of this tutorial. Add the following to:

/admin/structure/taxonomy/taxonomy_genre/add
NameDescription
Rock n’ RollA type of popular dance music originating in the 1950s, characterized by a heavy beat and simple melodies.
Dream PopA genre of music where timbre and texture are as important, if not more so, than melody and song structure.
RockHarsher and often self-consciously more serious than its predecessors, it was initially characterized by musical experimentation and drug-related or anti-Establishment lyrics.
SkiffleA kind of folk music with a blues or jazz flavor that was popular in the 1950s, played by a small group and often incorporating improvised instruments such as washboards
RnbA genre of popular African-American music that originated in the 1940s.
MerseybeatAfter bands from Liverpool and nearby areas beside the River Mersey is a pop and rock music genre that developed in the United Kingdom in the early 1960s.

No taxonomy without representation

Now that we’ve added a taxonomy vocabulary and populated a few taxonomy terms we are in a good place to add another endpoint to our API. One for our “genre” taxonomy.

Step 3: Add the files and folders for our endpoint

Please note: Because this is a tutorial series, endpoint versions are not uniform as you’d expect them to be with an official version release.

Let’s create our folder structures and necessary files first. Create the following folders:

  • plugins/restful/taxonomy — Further organization to group entities by entity type (in this case, taxonomies).
  • plugins/restful/taxonomy/genres — The name of our second restful plugin. Notice, again that I went with the plural form of the word genre, for endpoints, that is a best practice.

Now we will create a folder and two files inside of the genres folder which will help us define our first RESTful plugin.

  • plugins/restful/taxonomy/genres/0.1/ — This will hold our plugin definitions.
  • plugins/restful/taxonomy/genres/0.1/genres__0_1.inc — This will hold our plugin definitions.
  • plugins/restful/taxonomy/genres/0.1/ResteasyRestfulEntityGenresResource__0_1.class.php — This will hold our genres taxonomy class.

Your folder structure should look like this:

Step 4: Add a plugin definition for our taxonomy endpoint

As with our first tutorial we need to add in a ctools plugin definition for our taxonomy term. Why not take a look at the first tutorial if you need a refresher on what any of the following array attributes mean. Basically we are giving the RESTful module (via ctools) all that it needs to find the class files it needs to produce a new “genres” endpoint:

Add the code below to the plugin file at:

plugins/restful/taxonomy/genres/0.1/genres__0_1.inc
/**
 * @file
 * Genres plugin definition.
 */

$plugin = array(
  'label' => t('Genres'),
  'resource' => 'genres',
  'name' => 'genres__0_1',
  'entity_type' => 'taxonomy_term',
  'bundle' => 'taxonomy_genre',
  'description' => t('A resource that exposes the Genres taxonomy.'),
  'class' => 'ResteasyRestfulEntityGenresResource__0_1',
  'major_version' => 0,
  'minor_version' => 1,
);

So far this should look pretty familiar. Except for the entity_type parameter, where we have indicated taxonomy_term above this is exactly like the endpoint we created for a node. Now let’s take a look at the code we need to supply for the class that will enable the magic.

Step 5: Create our genre class file

Recall that in our previous work our classes extended a base node class:

class ResteasyRestfulEntityArtistsResource__0_2 extends RestfulEntityBaseNode

Taxonomy terms aren’t nodes though, so we need another class to implement. We will need to find the RestfulEntityBaseNode class – perhaps there is another choice. That class file is located in restful/plugins/restful/REstfulEntityBaseNode.php. which implements the RestfulEntityBase class. In that same folder there is another class which extends the same base class called RestEntityBaseTaxonomyTerm. This seems like our winner. Taking a look at this file, we see indeed that it is meant for this very purpose.

/**
 * A base implementation for "Taxonomy term" entity type.
 */
class RestfulEntityBaseTaxonomyTerm extends RestfulEntityBase {

Now that we’ve found an appropriate class let’s put our code together for our class, this code below will go into:

plugins/restful/taxonomy/genres/0.1/ResteasyRestfulEntityGenresResource__0_1.class.php
/**
 * @file
 * Contains ResteasyRestfulEntityGenresResource__0_1.
 */


/**
 * Implements ResteasyRestfulEntityGenresResource__0_1 class for "genres" vocabulary.
 */
class ResteasyRestfulEntityGenresResource__0_1 extends RestfulEntityBaseTaxonomyTerm   {

  /**
   * Overrides RestfulEntityBaseNode::publicFieldsInfo().
   */
  public function publicFieldsInfo() {
    $public_fields = parent::publicFieldsInfo();

    $public_fields['genreDescription'] = array(
      'property' => 'description',
    );

    $public_fields['weight'] = array(
      'property' => 'weight',
    );

    return $public_fields;
  }
}

All we need to do beyond extending the Base taxonomy class is define our public fields, just like we did with our node endpoint. Above I’ve added the description field and the weight field for the taxonomy.

Let me tell you how it will be

Step 6: Clear the cache

You’ll need to clear the cache now. But once you have, let’s head back to the API landing page.

Step 7: Visit the API landing page

Go to /api on your site. You should see something like this (there will be more but these are the relevant parts):

{
    "data":[
        {
            "label":"Genres",
            "description":"A resource that exposes the Genres taxonomy.",
            "name":"genres__0_1",
            "resource":"genres",
            "major_version":0,
            "minor_version":1,
            "self":"http://resteasy.local.dev/api/v0.1/genres"
        },
        {
            "label":"Artists",
            "description":"This resource presents artists from REST easy.",
            "name":"artists__0_2",
            "resource":"artists",
            "major_version":0,
            "minor_version":2,
            "self":"http://resteasy.local.dev/api/v0.2/artists"
        },
}

Already our genres endpoint is available and ready to be accessed by your API consumers.

If you visit the genres endpoint api/v0.1/genres you’ll see something like this:

{
    "data":[
        {
            "id":1,
            "label":"Rock n\u0027 Roll",
            "self":"http://resteasy.local.dev/api/v0.1/genres/1",
            "genreDescription":"u003Cpu003EA type of popular dance music originating in the 1950s, characterized by a heavy beat and simple melodies.u003C/pu003En",
            "weight":"0"
        },
        {
            "id":2,
            "label":"Dream Pop",
            "self":"http://resteasy.local.dev/api/v0.1/genres/2",
            "genreDescription":"u003Cpu003EA genre of music where timbre and texture are as important, if not more so, than melody and song structure.u003C/pu003En",
            "weight":"0"
        },
        {
            "id":3,
            "label":"Rock",
            "self":"http://resteasy.local.dev/api/v0.1/genres/3",
            "genreDescription":"u003Cpu003EHarsher and often self-consciously more serious than its predecessors, it was initially characterized by musical experimentation and drug-related or anti-Establishment lyrics.u003C/pu003En",
            "weight":"0"
        },
        {
            "id":4,
            "label":"Skiffle",
            "self":"http://resteasy.local.dev/api/v0.1/genres/4",
            "genreDescription":"u003Cpu003EA kind of folk music with a blues or jazz flavor that was popular in the 1950s, played by a small group and often incorporating improvised instruments such as washboardsu003C/pu003En",
            "weight":"0"
        },
        {
            "id":5,
            "label":"Rnb",
            "self":"http://resteasy.local.dev/api/v0.1/genres/5",
            "genreDescription":"u003Cpu003EA genre of popular African-American music that originated in the 1940s.u003C/pu003En",
            "weight":"0"
        },
        {
            "id":6,
            "label":"Merseybeat",
            "self":"http://resteasy.local.dev/api/v0.1/genres/6",
            "genreDescription":"u003Cpu003EAfter bands from Liverpool and nearby areas beside the River Mersey is a pop and rock music genre that developed in the United Kingdom in the early 1960s.u003C/pu003En",
            "weight":"0"
        }
    ],
    "count":6,
    "self":{
        "title":"Self",
        "href":"http://resteasy.local.dev/api/v0.1/genres"
    }
}

We can also target a specific id by using the following endpoint format api/v0.1/genres/{id}.

Here are the results from api/v0.1/genres/4

{
    "data":[
        {
            "id":"4",
            "label":"Skiffle",
            "self":"http://resteasy.local.dev/api/v0.1/genres/4",
            "genreDescription":"u003Cpu003EA kind of folk music with a blues or jazz flavor that was popular in the 1950s, played by a small group and often incorporating improvised instruments such as washboardsu003C/pu003En",
            "weight":"0"
        }
    ],
    "self":{
        "title":"Self",
        "href":"http://resteasy.local.dev/api/v0.1/genres/4"
    }
}

The cliffhanger

As you can see it is as easy to add a taxonomy endpoint as it was to add a node endpoint. You can apply any of the filtering techniques used in last weeks tutorial to filter the taxonomy results. In next week’s tutorial we’ll see what happens when node and taxonomy meet, the world of APIs might never be the same…


Read more of the REST easy series: