Skip to main content
Home
Drupal life hacks

Main navigation

  • Drupal
  • React
  • WP
  • Contact
  • About
User account menu
  • Log in

Breadcrumb

  1. Home

Invoked Controllers as a Service

By admin, 24 September, 2024

You can define a service that acts as a controller and use the __invoke() method to handle incoming requests. This approach can simplify your code because you don’t need to explicitly reference a specific method in the routing YAML file. Instead, you can reference the service ID directly, and Drupal will automatically call the __invoke() method.

Here’s how to implement it:

Steps to Define a Controller Service Using __invoke()

1. Define the Controller as a Service  


In your my_module.services.yml file, define a service that will act as a controller. This service will automatically have its __invoke() method called when it is referenced in the route.

yaml
services:
 my_module.custom_invoke_controller:
   class: Drupal\my_module\Controller\CustomInvokeController
   arguments: ['@some_dependency_service']  # Inject dependencies as needed
   tags:
     - { name: controller.service_arguments }

- my_module.custom_invoke_controller is the service ID.
- class refers to the PHP class implementing the controller logic.
- arguments allows you to inject services, such as a custom service, if necessary.

2. Create the Controller Class with __invoke() Method

 

Now, define the controller class. This class must include the __invoke() method, which will handle the request when the route is accessed.

php
namespace Drupal\my_module\Controller;
use Drupal\Core\Controller\ControllerBase;
use Drupal\my_module\Service\CustomService;
class CustomInvokeController extends ControllerBase {
 protected $customService;
// Constructor for injecting the service.
 public function __construct(CustomService $customService) {
   $this->customService = $customService;
 }
// The create() method to instantiate the service via the service container.
 public static function create(ContainerInterface $container) {
   return new static(
     $container->get('my_module.custom_service')
   );
 }
// The magic __invoke() method, which will be called by default.
 public function __invoke() {
   $data = $this->customService->getData();  // Access the service.
   return [
     '#markup' => $this->t('Data: @data', ['@data' => $data]),
   ];
 }
}

In this example:
- The __invoke() method is called automatically when the route is accessed.
- You can still inject services like CustomService through the constructor, making use of dependency injection.

3. Configure Routing to Use the Service

 

In the routing YAML file (my_module.routing.yml), reference the service ID without specifying a method. Drupal will automatically call the __invoke() method.

yaml
my_module.custom_invoke_page:
 path: '/custom-invoke-page'
 defaults:
   _controller: 'my_module.custom_invoke_controller'  # Reference the service ID
   _title: 'Custom Invoke Page'
 requirements:
   _permission: 'access content'

- _controller: Instead of pointing to a specific method (like CustomPageController::content), you just reference the service ID (my_module.custom_invoke_controller).
- When a user accesses /custom-invoke-page, Drupal will automatically call the __invoke() method in the CustomInvokeController.

Why Use __invoke()?

- Simplicity: You don’t need to specify the method name in the routing file. The __invoke() method is automatically called when the service is referenced.
- Clean Code: This approach can lead to cleaner code, especially for simple controllers that only need one action.
- Consistency: If your controller has only one main action, using __invoke() provides a consistent and predictable interface.

Summary

- Service Definition: Define your controller as a service in services.yml.
- Magic __invoke(): Implement the __invoke() method in the controller class to handle requests.
- Routing: Reference the service ID in the routing file without specifying a method. Drupal will automatically call the __invoke() method.
- Dependency Injection: You can still inject services or other dependencies into the controller, as with any other service-based controller.

Tags

  • #Drupal Planet
  • Invoked Controllers

Comments

About text formats

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.
Powered by Drupal