Custom REST Resources
Setting Up the Module
First, setup a new custom Drupal module – See Creating Custom Modules more detail instructions on how to do this.
Let’s create a module name Demo REST API
. To do so, create a new directory in/modules/custom/
named demo_rest_api
and add an info file for the module.
Example: demo_rest_api.info.yml
name: Demo REST API
description: Define's a custom REST Resource
package: Custom
type: module
core: 8.x
Once that is all in place, you should be able to enable your new module in the Drupal Admin.
Creating the Resource Plugins
In order to create a custom REST service, you will need to become acquainted with Plugins. Plugins are small pieces of functionality that are swappable. Plugins that perform similar functionality are of the same plugin type. In the case of our custom resource, we need to extend the ResourceBase
plugin, which can be found here
In order to implement a ResourceBase
plugin in our REST module, create a new fileDemoResource.php
in /src/Plugin/rest/resource/
directory of the Demo REST API module and add the following:
<?php
namespace Drupal\demo_rest_api\Plugin\rest\resource;
use Drupal\rest\Plugin\ResourceBase;
use Drupal\rest\ResourceResponse;
class DemoResource extends ResourceBase {
}
To review the above, we are setting the namespace for our PHP class and then using theResourceBase
class which we will be extending. We are also using theResourceResponse
class which will be used to send the response.
In order to configure our endpoint we will be utilizing Plugin annotations. Specifically, the Plugin implementation must be annotated with the @RestResource
annotation so that it can be discovered. Doing so will also allow you to set the Plugin id, label, and endpoint urls. A complete annotation will look like this:
/**
* Provides a Demo Resource
*
* @RestResource(
* id = "demo_resource",
* label = @Translation("Demo Resource"),
* uri_paths = {
* "canonical" = "/demo_rest_api/demo_resource"
* }
* )
*/
class DemoResource extends ResourceBase {
}
At this point the resource is now defined, and discoverable but it doesn’t actually do anything. To handle GET
requests, implement a static get
method on Demo Resource
and return an instance of ResourceResponse
/**
* Provides a Demo Resource
*
* @RestResource(
* id = "demo_resource",
* label = @Translation("Demo Resource"),
* uri_paths = {
* "canonical" = "/demo_rest_api/demo_resource"
* }
* )
*/
class DemoResource extends ResourceBase {
/**
* Responds to entity GET requests.
* @return \Drupal\rest\ResourceResponse
*/
public function get() {
$response = ['message' => 'Hello, this is a rest service'];
return new ResourceResponse($response);
}
}
Route parameters
The paths defined in the plugin's annotation can use placeholders the same way that routes do, whose values will be passed to the get() method if it has parameters whose names match the placeholders.
The request, route, and route match objects can also be passed to the get() method by typehinting them, the same way as controller callbacks.
Configuration
If you are using the REST UI contrib module, you should now be able to see it in the list of available endpoints and you should be able to configure the GET
method.
You can also manually import the configuration – See REST Web Services overview for detailed instructions on how to configure REST services.
Example REST resource config (<MODULE_NAME>/config/install/rest.resource.demo_resource_config.yml):
id: demo_resource_config
plugin_id: demo_resource
granularity: method
configuration:
GET:
supported_formats:
- json
supported_auth:
- basic_auth
This config file name needs to follow the convention of rest.resource.<my_id_string>.yml
and the id:
in the config file must match <my_id_string>
To add additional configuration information, you can use the settings.yml in config/optional like ./modules/rest/config/optional/rest.resource.entity.node.yml. In our case, it would be /modules/custom/demo_rest_api/config/optional/rest.resource.demo_resource.yml.
You should now be able to send a GET
request to /demo_rest_api/demo_resource?_format=json
with Content-Type
header set to application/json
andAuthorization
header set to your drupal user name and password and receive the following response:
{
"message": "Hello, this is a rest service"
}
POST Requests
To allow POST method usage, see https://www.drupal.org/docs/drupal-apis/restful-web-services-api/restful... . Note, in particular, the addition of the create
uri_path
in the annotation.
This post is part 1 in the 3 part series. Parts 2 & 3 will be coming soon.
Note : Custom REST Resources are not being discovered while naming module in camel casing last tested in Drupal version 8.5.6 (Similar to custom blocks are not being discovered while naming module in camel casing).
Help improve this page
You can:
- Log in, click Edit, and edit this page
- Log in, click Discuss, update the Page status value, and suggest an improvement
- Log in and create a Documentation issue with your suggestion