Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between Commands and Events in the context of Laravel 5?

So Laravel 5 was finally released yesterday with the final implementation of the command bus but I was wandering, what's the real difference in using a command bus over event mechanisms that we have in the previous releases?

Ok, I see the reason that it can be used to create commands from Request objects which is pretty useful but beyond that it seems to behave in a similar way even down to the whole queuing functionality for events now?

Can you please provide examples of use cases and where the pros and cons of either are?

like image 872
Peter Fox Avatar asked Feb 05 '15 12:02

Peter Fox


People also ask

What are events and commands?

Both are messages.They convey specific information; a command about the intent to do something, or an event about the fact that happened. From the computer's point of view, they are no different. Only the business logic and the interpretation of the message can find the difference between event and command.

What is an event in Laravel?

Laravel's events provide a simple observer pattern implementation, allowing you to subscribe and listen for various events that occur within your application. Event classes are typically stored in the app/Events directory, while their listeners are stored in app/Listeners .

What is command in Laravel?

Laravel makes it very convenient to define the input you expect from the user using the signature property on your commands. The signature property allows you to define the name, arguments, and options for the command in a single, expressive, route-like syntax.

What is event handling in Laravel?

Events provide a simple observer implementation which allows a user to subscribe and listen to various events triggered in the web application. All the event classes in Laravel are stored in the app/Events folder and the listeners are stored in the app/Listeners folder.


2 Answers

  • Commands are things about to happen right now. i.e. "CreateUser"
  • Events are things that have just occured right now - i.e. "UserSuccessfullyCreated"

The differences appear minor - but have some key differences.

  • Commands must be specifically called/dispatched. I.e. if you want to do CommandX - you must call CommandX somewhere.
  • Events respond to an event firing anywhere in your application. The great thing is multiple event handling classes can respond to the same event.

Lets do an example to illustrate it best. Lets say we create a user, and we want to send them a welcome email and also update our newsletter list.

In a Command Scenario would would do

AdminController {      function create() {             Bus::dispatch(new CreateUser(Auth::user());     } } 

then in our CommandClass - we would do

public function handle(CreateUser $auth) {      // 1. Create the user here      // 2. Send welcome email      // 3. Update our newsletter } 

But if we use events - we would do something like this in our CommandClass

public function handle(CreateUser $auth)     {          // 1. Create the user here          Event::fire(new UserWasCreated($user));     } 

then we can create as many events as we want to listen to that event and do something:

EventClassA

Event::listen('UserWasCreated', function($event) {     // 2. Send welcome email }); 

EventClassB

Event::listen('UserWasCreated', function($event) {     // 3. Update our newsletter }); 

The great thing is separation of concerns. The command "createuser" now does not need to worry itself about what happens after a user is created. It just needs to CreateUser.

Also - if we want to add another function after a user signs up - say enter them in a lotto draw - you can just add another Event Class and add a new event listener.

EventClassC

Event::listen('UserWasCreated', function($event) {     // 4. Register them in lotto }); 

Notice how we didnt need to touch the command CreateUser class code at all? This provides a true separation concerns of classes in a OOP style approach.

like image 55
Laurence Avatar answered Sep 22 '22 06:09

Laurence


I just want to share my understanding of this concept on top of the correct answer:

The main difference is that Commands can change a Model state, while Events just react to a state change.

COMMANDS:

Commands in Laravel represent the implementation of the Command design pattern.

The main adventages of Commands:

  • The can be accessed from anywhere
  • They are very easy to read by any other developer

To create a Command in Laravel 5:

You need to generate a command DTO (which can implement the SelfHandling interface). Using php artisan make:command {command-name}

Example: php artisan make:command Course/PostCourseCommand

The naming convention for commands: speak the business language and add postfix Command to it

To call (dispatch) the command from you controller, you can use:

$this->dispatch(new PostCourseCommand())

or

Bus::dispatch(new PostCourseCommand());

Side Note: The "dispatch from request” feature is a nice way to skip passing the variables to the command constructor one by one, instead it will resolve this for you:

Example:

$test_request = Request::create('/test', 'GET', [    'name' => 'Mahmoud',    'nickname' => 'Mega' ]);  $result = Bus::dispatchFrom(    CreateCourse::class, $test_request ); 

Finally:

You can separate the handler function and it’s logic from the command DTO to the Handlers directory, to do so:

  1. Generate a command handler via artisan

art handler:command --command="Course/PoatCourseCommand"

  1. remove the SelfHandling interface from the Command class so it will search for a handler to handle it.

EVENTS:

Events in Laravel represent the implementation of the Observer design pattern.

To create an Event in Laravel 5:

  1. use artisan: art make:event {event-name}

Example: art make:event LogSomething

  1. generate an event handler for that event

art handler:event LogSomething --event="LogSomething"

  1. register the event and it’s handler in the event service provider (app/Providers/EventServiceProvider.php)

Example:

protected $listen = [        \Zzz\Events\LogSomething::class => [ // event.name       \Zzz\Handlers\Events\LogSomething::class, //EventListener    ], ],     

To call (fire) an Event:

use:

Event::fire(New LogSomething());

or you can use the event helper

event(New LogSomething());

Side Note: alternatively you can generate an event by simply registering the event in the service provider then running this command.

php artisan event:generate << this will automatically add the two classes for you

Also you can listen to an event without creating an event handler or registering a lister in the listeners array, by just going to the event service prover and inside the boot function writing your event and its action (NOT RECOMMENDED). Example:

Event::listen('XXX\Events\DoSomethingElse', function($event) {     dd('handle me :)'); }); 

Finally: you can queue an event or even subscribe to multiple events from within the class itself..

like image 35
Mahmoud Zalt Avatar answered Sep 25 '22 06:09

Mahmoud Zalt