Welcome to the next step in your Headless Drupal journey! In this lesson, we will delve into defining REST plugins using the RestResource interface. Our goal is to help you create custom APIs in Drupal that can serve data across platforms.
What is RestResource?
The RestResource plugin in Drupal allows you to expose custom functionalities and data as RESTful APIs. By leveraging the RestResource interface, you can define how your data is accessed by different HTTP methods such as GET, POST, PATCH, DELETE, etc.
Prerequisites
Before proceeding, ensure you have a basic understanding of PHP and have a Drupal 9 installation ready, as outlined in the earlier lessons of this series. Also, ensure you have the RESTful Web Services module enabled.
Creating a Custom RestResource Plugin
To create a custom RestResource, we need to define a plugin class and inform Drupal of its existence using annotations. Here's a step-by-step guide:
Step 1: Directory Structure
First, decide on the module name for your RestResource. For this example, let's call it custom_rest_api.
custom_rest_api/ ├── src/ │ ├── Plugin/ │ │ └── rest/ │ │ └── resource/
Create these directories within your custom module. This structure plays a vital role in organizing your code and declaring exactly where the plugin resides.
Step 2: Define the RestResource Class
Create a PHP file within the resource
directory. Name it ExampleResource.php
.
<?php
namespace Drupal\custom_rest_api\Plugin\rest\resource;
use Drupal\rest\Plugin\ResourceBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\rest\ResourceResponse;
use Drupal\Core\Session\AccountProxyInterface;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
/**
* Provides a resource example.
*
* @RestResource(
* id = "example_resource",
* label = @Translation("Example Resource"),
* uri_paths = {
* "canonical" = "/api/example"
* }
* )
*/
class ExampleResource extends ResourceBase {
/**
* A current user instance.
*
* @var \Drupal\Core\Session\AccountProxyInterface
*/
protected $currentUser;
/**
* Constructs a new ExampleResource object.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Session\AccountProxyInterface $current_user
* A current user instance.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, AccountProxyInterface $current_user) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->currentUser = $current_user;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('current_user')
);
}
/**
* Responds to GET requests.
*
* Returns a string content.
*
* @return \Drupal\rest\ResourceResponse
* The response containing the data.
*
* @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
* Throws exception if access denied.
*/
public function get() {
if (!$this->currentUser->hasPermission('access content')) {
throw new AccessDeniedHttpException();
}
$data = ['message' => 'Hello, this is a custom REST resource!'];
return new ResourceResponse($data);
}
}
Step 3: Enable the Plugin
With your plugin class in place, enable the module via Drush or through Drupal's admin interface. Make sure the route is accessible by configuring permissions and ensuring the Restful Web Services module allows access per our previous lesson.
Testing Your Resource
Navigate to /api/example
(as specified in your uri_paths
) via your browser or a tool like Postman. Ensure you have the proper permissions set up, as the example checks for 'access content' permission.
Conclusion
You should now have a working REST plugin using the RestResource interface. This serves as the backbone for creating custom API endpoints in Drupal. When implemented effectively, it empowers you to expose tailored data and functionality for your headless applications.
Preview of Next Lesson
In our next lesson, we will dive into Setting up Routes and Methods in .routing.yml. You’ll learn how to define and configure routes, which are pivotal in making web resources accessible via various HTTP methods. Stay tuned as we continue to unravel the power of custom APIs in Drupal!