How to Create and Use Drupal 8+ Services: A Detailed Guide with Practical Code

drupal services

Drupal, the open-source content management system, has come a long way since its inception. With the release of Drupal 8, we saw a massive shift in the underlying architecture: the adoption of a more object-oriented programming approach using Symfony components. One notable component that was introduced in Drupal 8 is the service container, which has since improved the way modules and themes are developed.

This article will provide an in-depth look at Drupal 8+ services and how they can be utilized to create efficient, modular, and maintainable code. Additionally, we will walk through a sample code for better understanding.

What Are Drupal Services?

In Drupal 8+, services are reusable components or objects that provide specific functionalities. They are designed to follow the Dependency Injection (DI) design pattern and are usually stored in the service container. This design pattern allows you to create loosely-coupled code, making it easier to manage and maintain.

Some examples of Drupal services include the Database connection, Entity Manager, and Renderer.

Creating a Custom Service

To provide a custom service in your module, you need to create a services.yml file within your module’s root directory. This file is used to define your new service’s class and any dependencies it may have. All services are created as instances of PHP classes.

Step 1: Create the services.yml File

  1. First, create a YAML file with the name yourmodule.services.yml, replacing “yourmodule” with your module’s machine name.
  2. Define the service in the YAML file, including its class and any necessary services.

Here’s a sample services.yml file:

services:
  yourmodule.sample_service:
    class: Drupal\yourmodule\SampleService
    arguments: ['@database']

Step 2: Create the Service Class

  1. Create a new directory at src within your module’s root directory.
  2. Inside the src directory, create a PHP file with the same name as the class defined in the YAML file. In our example, it would be SampleService.php.
  3. Define the class in the new file, extend any necessary base classes, and implement any needed interfaces. Use dependency injection to construct the class.

Here’s a sample SampleService.php file:

// Define the namespace for this class.
namespace Drupal\yourmodule;

// Import the Drupal\Core\Database\Connection class so it can be used within this class.
use Drupal\Core\Database\Connection;

// Define a class called SampleService.
class SampleService {

  // Define a property called $database that can be accessed within this class.
  protected $database;

  // Define a constructor method that takes a Connection object and assigns it to the $database property.
  public function __construct(Connection $database) {
    $this->database = $database;
  }

  // Define a method called fetchAllUsers that returns all users from the 'users' table in the database.
  public function fetchAllUsers() {
    // Create a new select query on the 'users' table.
    $query = $this->database->select('users', 'u');

    // Select the 'uid', 'name', and 'mail' fields from the 'users' table.
    $query->fields('u', ['uid', 'name', 'mail']);

    // Execute the query and fetch all results as an associative array.
    return $query->execute()->fetchAll();
  }
}

In this example, we’ve created a simple custom service that fetches all users from the database. As we can see, we’ve used dependency injection to inject the database connection into the service.

Step 3: Using the Custom Service

Accessing your custom service couldn’t be simpler. In your module, theme, or another service, use the \Drupal class to call your custom service, like this:

$sample_service = \Drupal::service('yourmodule.sample_service');
$all_users = $sample_service->fetchAllUsers();

And that’s it! You’ve successfully created a custom service in Drupal 8+.

Conclusion

Drupal 8+ services enable developers to write clean, reusable, and well-contained code. By creating custom services and utilizing the Dependency Injection (DI) design pattern, developers can efficiently implement modular features and enhancements to Drupal projects.

With a better understanding of Drupal services and some sample code at hand, you now have the tools to create your own custom services and improve the maintainability and modularity of your Drupal projects.


Posted

in

, ,

by