Skip to content

Look up a URL alias mapping with DataProviderDbQuery

Gonzalo Guevara edited this page Mar 15, 2018 · 4 revisions

(The following is also covered in a blog post at Creating a RESTful API URL Alias Lookup in Drupal)

As detailed here, you can create custom data providers as API endpoints. A perfect example of this is the standard url alias mapping that is provided in Drupal core with the Path module; the entity is accessed via a clean URL (e.g. /blogs/my/blog/title), the mapping to the base node/nid value is obtained by querying the url_alias table, and the base URL is used to load the entity itself. This is a functionality not made available in RESTful out of the box, so it has to be created.

Annotation

As with any 7.x-2.x RESTful plugin, the plugin is defined in the annotation. Here is the annotation for our URLAlias__1_0 class:

/**
 * Class URLAlias__1_0
 * @package Drupal\restful_tutorial\Plugin\resource\url_alias
 *
 * @Resource(
 *   name = "urlalias:1.0",
 *   resource = "urlalias",
 *   label = "URL Alias",
 *   description = "Gets the entity id from a URL alias.",
 *   authenticationTypes = TRUE,
 *   authenticationOptional = TRUE,
 *   dataProvider = {
 *     "tableName": "url_alias",
 *     "idColumn": "alias",
 *     "primary": "pid",
 *     "idField": "pid",
 *   },
 *   majorVersion = 1,
 *   minorVersion = 0,
 *   class = "URLAlias__1_0"
 * )
 */

The main difference between this annotation and one for an entity endpoint is the dataProvider key. The two most important items are:

  • tableName - As the name implies, the name of the table you are querying.
  • idColumn - The column to which the values passed in the URL will be compared.

In this case, we need to pass the clean URL and get the base URL, so we will be querying the alias column.

Class

Next is the class itself.

class URLAlias__1_0 extends ResourceDbQuery implements ResourceInterface {

  /**
   * {@inheritdoc}
   */
  protected function publicFields() {
    $public_fields['pid'] = array(
      'property' => 'pid'
    );

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

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

    return $public_fields;
  }
}

As with any other endpoint, we need to declare our public fields. Also the names that we give need to match the values in the dataProvider in the annotation.

One slight difference between the use of the publicFields method for this data provider is that you don't use this line at the beginning:

$public_fields = parent::publicFields();

This is because you extend the ResourceDbQuery class, which is an abstract class that does not have a publicFields() method. If you do include that line, you will get an error saying Cannot call abstract method publicFields().

Here is the final code:

/**
 * Contains \Drupal\restful_tutorial\Plugin\resource\url_alias
 */

namespace Drupal\restful_tutorial\Plugin\resource\url_alias;

use Drupal\restful\Plugin\resource\ResourceDbQuery;
use Drupal\restful\Plugin\resource\ResourceInterface;

/**
 * Class URLAlias__1_0
 * @package Drupal\restful_tutorial\Plugin\resource\url_alias
 *
 * @Resource(
 *   name = "urlalias:1.0",
 *   resource = "urlalias",
 *   label = "URL Alias",
 *   description = "Gets the entity id from a URL alias.",
 *   authenticationTypes = TRUE,
 *   authenticationOptional = TRUE,
 *   dataProvider = {
 *     "tableName": "url_alias",
 *     "idColumn": "alias",
 *     "primary": "pid",
 *     "idField": "pid",
 *   },
 *   majorVersion = 1,
 *   minorVersion = 0,
 *   class = "URLAlias__1_0"
 * )
 */

class URLAlias__1_0 extends ResourceDbQuery implements ResourceInterface {

  /**
   * {@inheritdoc}
   */
  protected function publicFields() {
    $public_fields['pid'] = array(
      'property' => 'pid'
    );

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

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

    return $public_fields;
  }
}

Querying and Final Output

Querying the new urlalias endpoint with the following URL:

http://mysite/api/urlalias/my-blog-title

will generate the following JSON output:

{
  "data": {
    "type": "urlalias",
    "id": "154177",
    "attributes": {
      "pid": "154177",
      "source": "node/97783",
      "alias": "blogs/my-blog-title"
    },
    "links": {
      "self": "http://mysite/api/v1.0/urlalias/154177"
    }
  },
  "links": {
    "self": "http://mysite/blogs/my-blog-title"
  }
}
Clone this wiki locally