> ## Content Index
> Fetch the complete content index at: https://madewithlove.com/blog/llms.txt
> Use this file to discover other available public pages before exploring further.

# Laravel 5 Command-Oriented Approach
- URL: https://madewithlove.com/blog/laravel-5-command-oriented-approach/
- Published: 2015-01-02T14:36:29.000Z
- Updated: 2026-05-29T11:59:02.000Z
- Author: Tony Messias
- Tags: Engineering, Tutorials, Laravel

A lot of shiny things around the [Laravel](https://madewithlove.com/blog/performance-tips-for-laravel/) world that I would like to talk about, so I chose the new CommandBus that Laravel 5 brings by default. To start I’d like to say that it’s pretty damn cool.

## Command-Oriented Architecture

I’m not gonna explain in detail this approach, but I’m going to give a brief introduction on the topic and link a few more pieces of content at the bottom.

Basically, we should describe our application in commands to make our intentions explicit. Let’s say you have a subscription system on your app, you’d have a “SubscribeUserCommand” class, or something similar, that maps to its own handler, in this case, “SubscribeUserCommandHandler”. By doing so you actually decouple your application from the transport layer (HTTP, CLI, queue job, event handler, etc..). It means that you can *dispatch* this command from a Controller or a console command (CLI) with no trouble.

## Laravel way

We used to implement this approach using some packages (see [laracasts/commander](https://github.com/laracasts/Commander?ref=madewithlove.com)), which are actually pretty neat and work like a charm. However, Laravel 5 brings its own CommandBus with a plus: it can handle commands (AND EVENTS!!!) in the background (queues).

A typical command looks like this:

***app/Commands/SubscribeUserCommand.php***

```
<?php 

amespace App\Commands;

use App\Subscriptions\MembershipType;

class SubscribeUserCommand extends Command
{
  public $userId;
  public $membershipType;

  public function __construct($userId, MembershipType $membershipType)
  {
    $this->userId = $userId;
    $this->membershipType = $membershipType;
  }

}
```

Then you should have a handler like this:

***app/Handlers/Commands/SubscribeUserCommandHandler.php***

```
<?php 

namespace App\Handlers\Commands;

use App\Commands\SubscribeUserCommand;
use Illuminate\Contracts\Events\Dispatcher;
use App\Payment\PaymentInterface;

class SubscribeUserCommandHandler
{
  private $userRepository;
  private $events;
  private $payment;

  public function __construct(
    UserRepository $userRepository,
    Dispatcher $events,
    PaymentInterface $payment
  ) {
    $this->userRepository = $userRepository;
    $this->events = $events;
    $this->payment = $payment;
  }

  public function handle(SubscribeUserCommand $command)
  {
    $user = $this->userRepository->find($command->userId);

    $user->subscribe($command->membershipType, $this->payment);

    $this->dispatchEvents($user->releaseEvents());
  }

  /**
   * @param array $events
   * @return void
   */
  private function dispatchEvents(array $events)
  {
    foreach ($events as $event)
      $this->events->fire($event);
    }
  }
}
```

Which you can dispatch, let’s say, from your controller like so:

***app/Http/Controllers/SubscriptionsController.php***

```
<?php 

namespace App\Http\Controllers;

use Illuminate\Contracts\Auth\Guard;
use App\Commands\SubscribeUserCommand;

class SubscriptionControllers extends Controller
{
  private $auth;

  public function __construct(Guard $auth)
  {
    $this->middleware('auth');
    $this->auth = $auth;
  }

  public function subscribe(SubscribeUserRequest $request)
  {
    $command = new SubscribeUserCommand(
      $this->auth->user()->id,
      MembershipType::build($request->get("membership_type"))
    );

    $this->dispatch($command);

    return redirect()->route("home");
  }
}
```

The *dispatch* method is inherited from the Controller class (which uses the `IlluminateFoundationBusDispatchesCommands`) and it maps commands to handlers. Cool stuff. This example works synchronously. If you need to handle the command in background (queue jobs) you just have to implement the `IlluminateContractsQueueShouldBeQueued` interface on your command like so:

***app/Commands/SubscribeUserCommand.php***

```
<?php 

namespace App\Commands;

use App\Subscriptions\MembershipType;
use Illuminate\Contracts\Queue\ShouldBeQueued;

class SubscribeUserCommand extends Command implements ShouldBeQueued
{
  public $userId;
  public $membershipType;

  public function __construct(
    $userId,
    MembershipType $membershipType
  ) {
    $this->userId = $userId;
    $this->membershipType = $membershipType;
  }
}
```

That is it! Well, actually you have to setup the queue config on `config/queue.php`, but I’m making a point here.

## Handling Events in background

As I said, it is also possible to handle events in the background, let’s see an example. Let’s assume your User you have a *subscribe* named constructor on your model that builds the user instance and saves it (Eloquent/ActiveRecord). Your model should look like:

***app/User.php***

```
<?php 

namespace App;

use Illuminate\Database\Eloquent\Model;
use App\Events\UserSubscribedEvent;
use App\Subscriptions\MembershipType;
use App\Payment\PaymentInterface;

class User extends Model
{
  // ...
  public function subscribe(
    MembershipType $membershipType,
    PaymentInterface $payment
  ) {
    $payment->purchaseSubscription($this, $membershipType);

    $this->subscription()->create($membershipType->toArray());

    $this->raise(new UserSubscribedEvent(
      $this->id,
      $membershipType
    ));

    return $this;
  }

  // ...
}
```

Your event class is just a DTO and looks like this:

***app/Events/UserSubscribedEvent.php***

```
<?php

namespace App\Events;

use Illuminate\Queue\SerializesModels;
use App\Subscriptions\MembershipType;

class UserSubscribedEvent extends Event
{
  use SerializesModels;

  public $userId;
  public $membershipType;

  public function __construct(
    $userId,
    MembershipType $membershipType
  ) {
    $this->userId = $userId;
    $this->membershipType = $membershipType;
  }
}
```

Then you have a handler like so:

***app/Handlers/Events/UserSubscribedEventHandler;***

```php
<?php

namespace App\Handlers\Events;

use App\Events\UserSubscribedEvent;
use App\Mailers\UserMailer;

class UserSubscribedEventHandler
{
  public function __construct(
    UserMailer $mailer,
    UserRepository $userRepository
  ) {
    $this->mailer = $mailer;
    $this->userRepository = $userRepository;
  }

  public function handle(UserSubscribedEvent $event)
  {
    $user = $this->userRepository->find($event->userId);
   
    $this->mailer->sendTo($user, $this->buildMessage(
      $event->membershipType
    ));
  }

  // ... the buildMessage should be private or protected
}
```

To register your handler just go to `app/Providers/EventServiceProvider.php` and add your listener to the `$listen` property, like so:

```php
<?php 

namespace App\Providers;

use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;

class EventServiceProvider extends ServiceProvider
{
  /**
   * The event handler mappings for the application.
   *
   * @var array
   */
  protected $listen = [
    AppEventsUserSubscribedEvent::class => [
      AppHandlersEventsUserSubscribedEventHandler::class
    ]
  ];
}
```

This action is executed synchronously, it means that your user is waiting for the event handler to act before being redirected to the application.

To handle the event in background you just have to implement the same `IlluminateContractsQueueShouldBeQueued` interface on your event handler class, like so:

***app/Handlers/Events/UserSubscribedEventHandler;***

```php
<?php

namespace App\Handlers\Events;

use App\Events\UserSubscribedEvent;
use App\Mailers\UserMailer;
use Illuminate\Contracts\Queue\ShouldBeQueued;

class UserSubscribedEventHandler implements ShouldBeQueued
{
  public function __construct(
    UserMailer $mailer,
    UserRepository $userRepository
  ) {
    $this->mailer = $mailer;
    $this->userRepository = $userRepository;
  }

  public function handle(UserSubscribedEvent $event)
  {
    $user = $this->userRepository->find($event->userId);

    $this->mailer->sendTo($user, $this->buildMessage(
      $event->membershipType
    ));
  }

  // ... the buildMessage should be private or protected
}
```

Oh, by the way, you just give the event class to the event dispatcher, like so (using the Facade):

```
<?php

// somewhere in your application
use App\Events\UserSubscribedEvent;

Event::fire(new UserSubscribedEvent($userId, $membershipType));
```

## Conclusion

That is it. To sum up, I like to think that Commands can change state, while Events just react to these state changes and if an Event handler has to change anything it MUST do it through Commands.

This command bus looks pretty cool. Fun fact: you can have multiple event listeners/handlers where some of them executes synchronously and others execute asynchronously. I loved it, to make it work before we had to have an event listener that add a job to the queue and then handle the event on the job handler. Now it’s pretty damn simple.

## Useful resources

- [DevDiscussions – The Command Bus](https://www.youtube.com/watch?v=fbSYZFZCFS0&ref=madewithlove.com)
- [Laracast about the Laravel 5 Command bus](https://laracasts.com/lessons/laravel-5-commands?ref=madewithlove.com)
- [Laracast series about Commands and Domain Events](https://laracasts.com/series/commands-and-domain-events?ref=madewithlove.com)
- [Task-based UI](https://cqrs.wordpress.com/documents/task-based-ui/?ref=madewithlove.com)
- [Command Bus by Shawn McCool](https://shawnmc.cool/command-bus?ref=madewithlove.com)
- [CRUD is an antipattern](https://verraes.net/2013/04/crud-is-an-anti-pattern/?ref=madewithlove.com)