Backend Development - Custom Drush Commands

We now arrive at the final topic of Level 2 – Backend Development.

Throughout this series, we have built a complete backend architecture inside the weeklydrupal_demo module:

  • Custom modules
  • Routes and controllers
  • Forms and AJAX
  • Field types, widgets, and formatters
  • Entity CRUD
  • Typed Data
  • Queue, Batch, and Cron
  • Validation constraints

Now we add one more powerful backend capability: Custom Drush Commands.

Drush commands allow you to execute backend logic directly from the command line.

This is essential for:

  • Running maintenance tasks
  • Triggering imports
  • Debugging data
  • Automating workflows
  • Operating Drupal in production environments

By the end of this article, you will understand:

  • What Drush commands are
  • How Drupal discovers custom commands
  • How to define a command class
  • How dependency injection works in Drush
  • How to integrate commands with services and Entity API

1. What Is Drush

Drush is the command-line tool for Drupal.

Common built-in commands:

  • drush cr (cache rebuild)
  • drush cron
  • drush status

Custom commands allow your module to expose its own CLI functionality.

In simple terms:

Drush = backend execution without a browser


2. Where Custom Drush Commands Live

Custom Drush command classes live in:

src/Commands

Drupal discovers them automatically if Drush is installed.


3. Creating a Custom Drush Command

File path:

weeklydrupal_demo/src/Commands/DemoCommands.php

DemoCommands.php

<?php

namespace Drupal\weeklydrupal_demo\Commands;

use Drush\Commands\DrushCommands;
use Drupal\Core\Entity\EntityTypeManagerInterface;

class DemoCommands extends DrushCommands {

  protected EntityTypeManagerInterface $entityTypeManager;

  public function __construct(EntityTypeManagerInterface $entityTypeManager) {
    parent::__construct();
    $this->entityTypeManager = $entityTypeManager;
  }

  /**
   * Creates a demo article.
   *
   * @command weeklydrupal:create-article
   * @aliases wd-create
   */
  public function createArticle($title = 'Drush Created Article') {

    $node = $this->entityTypeManager->getStorage('node')->create([
      'type' => 'article',
      'title' => $title,
      'status' => 1,
    ]);

    $node->set('field_rating', 5);
    $node->save();

    $this->logger()->success('Article created with ID: ' . $node->id());
  }

}

4. Understanding the Namespace

namespace Drupal\weeklydrupal_demo\Commands;

Explanation:

  • Drupal – Core namespace root
  • weeklydrupal_demo – Module machine name
  • Commands – Folder inside src

PSR-4 autoloading maps namespace to folder structure.


5. Understanding the Command Annotation

@command weeklydrupal:create-article
@aliases wd-create
  • @command defines the CLI command name
  • @aliases defines shortcuts

Command can now be run as:

drush weeklydrupal:create-article

or

drush wd-create

6. Dependency Injection in Drush Commands

Notice:

public function __construct(EntityTypeManagerInterface $entityTypeManager)

Drupal injects services into the command class.

This allows:

  • Clean architecture
  • Reusable services
  • Testable code

Avoid using static \Drupal:: calls in production-ready commands.


7. Connecting Drush to Services

Better architecture pattern:

  • Drush command calls a service
  • Service performs entity CRUD
  • Business logic remains centralized

Example concept:

public function createArticle($title) {
  $id = $this->demoService->createArticle($title);
  $this->logger()->success('Created node ID: ' . $id);
}

This keeps command classes thin.


8. Command Arguments and Options

Example with argument:

/**
 * @command weeklydrupal:create-article
 * @param string $title
 */
public function createArticle($title) {
  // Logic here
}

Example with option:

/**
 * @option rating
 */

Options allow flexible CLI usage.


9. Real-World Use Cases

Custom Drush commands are commonly used for:

  • Data imports
  • Data cleanup
  • Batch reprocessing
  • Cache invalidation
  • Debugging entity data
  • Running background tasks manually

Enterprise Drupal environments rely heavily on Drush.


10. Common Mistakes to Avoid

  • Writing heavy logic directly in command class
  • Skipping dependency injection
  • Not validating arguments
  • Forgetting access considerations

Drush commands can bypass UI safeguards. They must be written carefully.


11. Learning by Building: weeklydrupal_demo

To complete:

  • Create the DemoCommands class
  • Inject entity type manager
  • Call service for entity creation
  • Test via terminal

This connects:

  • Services
  • Entity CRUD
  • Validation
  • Logging
  • Backend automation

12. Why Custom Drush Commands Matter

Understanding custom Drush commands allows you to:

  • Operate Drupal at scale
  • Automate complex backend tasks
  • Maintain systems safely
  • Debug and inspect data efficiently

Drush is an essential tool for backend Drupal developers.