Creating a Batch Service in Drupal 10: how-to and example code

Drupal 10 has introduced a new way of handling batch operations, making it easier to perform complex tasks in the background. In this tutorial, we'll explore how to create a batch service in Drupal 10, complete with example code.

What is a Batch Service?

A batch service is a mechanism in Drupal that allows you to perform a series of operations in the background, without blocking the main request. This is particularly useful for tasks that take a long time to complete, such as importing large datasets or sending newsletters.

Step 1: Create a New Module

To create a batch service, we'll need to create a new module. Let's call it `my_batch_service`. Create a new directory in the `modules/custom` directory of your Drupal installation, and add the following files:


// my_batch_service.info.yml
name: My Batch Service
description: A custom batch service module
package: Custom
type: module
core: 10.x

// my_batch_service.module
use Drupal\Core\Batch\BatchBuilder;
use Drupal\Core\Batch\BatchExecutableInterface;

/**
 * @file
 * Contains \Drupal\my_batch_service\MyBatchService.
 */

namespace Drupal\my_batch_service;

class MyBatchService implements BatchExecutableInterface {
  // We'll add our batch logic here
}

Step 2: Define the Batch Operation

In the `MyBatchService` class, we need to define the batch operation. This is where we'll specify what tasks we want to perform in the background.


// my_batch_service.module
use Drupal\Core\Batch\BatchBuilder;
use Drupal\Core\Batch\BatchExecutableInterface;

/**
 * @file
 * Contains \Drupal\my_batch_service\MyBatchService.
 */

namespace Drupal\my_batch_service;

class MyBatchService implements BatchExecutableInterface {
  public function process($item, &$context) {
    // Perform some operation on the item
    \Drupal::logger('my_batch_service')->info('Processing item @item', ['@item' => $item]);
  }

  public function finished($success, $results, $operations) {
    // Handle the results of the batch operation
    if ($success) {
      \Drupal::messenger()->addMessage('Batch operation completed successfully');
    }
    else {
      \Drupal::messenger()->addError('Batch operation failed');
    }
  }
}

Step 3: Create the Batch Builder

Next, we need to create a batch builder that will define the batch operation and execute it.


// my_batch_service.module
use Drupal\Core\Batch\BatchBuilder;
use Drupal\Core\Batch\BatchExecutableInterface;

/**
 * @file
 * Contains \Drupal\my_batch_service\MyBatchService.
 */

namespace Drupal\my_batch_service;

class MyBatchService implements BatchExecutableInterface {
  // ...

  public static function createBatch($items) {
    $batch_builder = new BatchBuilder();
    $batch_builder->setTitle('My Batch Service');
    $batch_builder->setInitMessage('Initializing batch operation...');
    $batch_builder->setProgressMessage('Processing @current of @total items...');
    $batch_builder->setErrorMessage('Error processing item @item');
    $batch_builder->setFinishedMessage('Batch operation completed');

    $batch_builder->addOperation([
      'my_batch_service_process',
      [$items],
    ]);

    return $batch_builder;
  }
}

Step 4: Execute the Batch Operation

Finally, we need to execute the batch operation. We can do this by calling the `createBatch` method and passing in the items we want to process.


// my_batch_service.module
use Drupal\Core\Batch\BatchBuilder;
use Drupal\Core\Batch\BatchExecutableInterface;

/**
 * @file
 * Contains \Drupal\my_batch_service\MyBatchService.
 */

namespace Drupal\my_batch_service;

class MyBatchService implements BatchExecutableInterface {
  // ...

  public static function executeBatch($items) {
    $batch_builder = self::createBatch($items);
    $batch_builder->execute();
  }
}

That's it! We've now created a batch service in Drupal 10 that can perform a series of operations in the background. To test the batch service, simply call the `executeBatch` method and pass in the items you want to process.

 

Saved you some valuable time?

Buy me a drink 🍺 to keep me motivated to create free content like this!