-
Notifications
You must be signed in to change notification settings - Fork 173
Look up a URL alias mapping with DataProviderDbQuery
(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.
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.
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 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"
}
}