Skip to content

Commit

Permalink
Merge pull request #39 from UFOMelkor/feature/documentation
Browse files Browse the repository at this point in the history
Documentation
  • Loading branch information
codeliner authored Oct 29, 2017
2 parents b613586 + 404a1a1 commit 8845038
Show file tree
Hide file tree
Showing 8 changed files with 256 additions and 85 deletions.
3 changes: 3 additions & 0 deletions doc/bookdown.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
"content": [
{"intro": "../README.md"},
{"getting_started": "getting_started.md"},
{"routing": "routing.md"},
{"plugins": "plugins.md"},
{"profiler": "profiler.md"},
{"configuration_reference": "configuration_reference.md"}
],
"target": "./html",
Expand Down
119 changes: 34 additions & 85 deletions doc/getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This documentation covers just the configuration of the Prooph Service Bus in Symfony.
To inform yourself about the ProophServiceBus please have a look at the
[official documentation](http://getprooph.org/service-bus/intro.html).
[official documentation](http://docs.getprooph.org/service-bus/).

## Download the Bundle

Expand All @@ -16,6 +16,7 @@ at the root of your Symfony project.

To start using this bundle, register the bundle in your application's kernel class:
```php
<?php
// app/AppKernel.php
// …
class AppKernel extends Kernel
Expand All @@ -34,127 +35,69 @@ class AppKernel extends Kernel
}
```

or, if you are using [the new flex structure](https://symfony.com/doc/current/setup/flex.html):
```php
<?php
// config/bundles.php

return [
// …
Prooph\Bundle\ServiceBus\ProophServiceBusBundle::class => ['all' => true],
];
```

## Configure your first command bus

There are three different types of message bus supported by the ProophServiceBus.
While they have totally different purposes, their configuration is nearly the same.
As an example, we will configure a command bus.
For query bus and event bus, please have a look at the [configuration reference](./configuration_reference.html).

The command bus is configured in `app/config/config.yml`:
The command bus is configured in `app/config/config.yml`
(or `config/packages/prooph_service_bus.yaml` if you are using flex):
```yaml
# app/config/config.yml
prooph_service_bus:
command_buses:
acme_command_bus: ~
```
That's all you need to define a (useless) command bus. Let's make it useful.
### Route to a command handler
There are two ways to route a command to a command handler.
You can simply add it to the ProophServiceBus configuration:
```yaml
# app/config/config.yml
prooph_service_bus:
command_buses:
acme_command_bus:
router:
routes:
'Acme\Command\RegisterUser': '@acme.command.register_user_handler'
```
In this case `Acme\Command\RegisterUser` would be the name of your command (which usually corresponds to its class name)
and `acme.command.register_user_handler` the service-id of the handler (that you have to normally configure in Symfony).
The `@` before the service-id can be omitted, but it provides auto completion in some IDEs.

> **Note**: When configuring the event bus you can pass an array of service IDs for each event instead of a single service ID.
> This is necessary because events can be routed to multiple event handlers.
### Route your first command handler
The main benefit of this way is that you have all command handlers registered in one place.
But it has also some drawbacks:
You have to configure every command handler for itself and add it to the routes of the command bus,
which implies changes at two different places for adding one command handler.
Also, because the name of the command usually corresponds to the class of the command, it is vulnerable for refactoring.

Therefore, you can also route a command to a command handler using tags. This will look like this:
We assume that you already have a command `Acme\Command\RegisterUser`
and a command handler `Acme\Command\RegisterUserHandler`.
We will define the command handler as a regular service in Symfony:
```yaml
# app/config/services.yml
# app/config/services.yml or (flex) config/packages/prooph_service_bus.yaml
services:
acme.command.register_user_handler:
class: Acme\Command\RegisterUserHandler
tags:
- { name: 'prooph_service_bus.acme_command_bus.route_target' }
```
The bundle will try to detect the name of the command by itself.

If this feels like too much magic or if the detection fails, you can still pass the name of the command as attribute:
To route the command `Acme\Command\RegisterUser` to this service, we just need to add a tag to this definition:
```yaml
# app/config/services.yml
services:
acme.command.register_user_handler:
class: Acme\Command\RegisterUserHandler
tags:
- { name: 'prooph_service_bus.acme_command_bus.route_target', message: 'Acme\Command\RegisterUser' }
```

> **Hint:** If you rely on automatic message detection and your handler handles multiple messages of the same message bus,
> you need to tag the handler just once.

Both options have its advantages and disadvantages.
The result is the same, so it's up to your personal preference which option you choose.

### Add a plugin

[Plugins](http://getprooph.org/service-bus/plugins.html) are a great way to expand a message bus.
Let's assume that we want to use the `HandleCommandStrategy` for our command bus.
Again, there are two options to do this.
Both require to define a service for the plugin:
```yaml
# app/config/services.yml
services:
acme.prooph.plugin.handle_command_strategy:
class: Prooph\ServiceBus\Plugin\InvokeStrategy\HandleCommandStrategy
```

Let's start with the first option, modifying our `app/config/config.yml`:
```yaml
# app/config/config.yml
prooph_service_bus:
command_buses:
acme_command_bus:
plugins:
- "acme.prooph.plugin.handle_command_strategy"
```
That is all you need to do to register the plugin.

Now we will have a look at the other option, using tags.
Therefore, we just need to add a tag to the service configuration:
```yaml
# app/config/services.yml
services:
acme.prooph.plugin.handle_command_strategy:
class: Prooph\ServiceBus\Plugin\InvokeStrategy\HandleCommandStrategy
tags:
- { name: 'prooph_service_bus.acme_command_bus.plugin' }
- { name: 'prooph_service_bus.acme_command_bus.route_target' }
```

> **Hint:** If you want to register the plugin for more than one message bus, you can use
> - `prooph_service_bus.command_bus.plugin` to register it for every command bus (resp. `prooph_service_bus.query_bus.plugin` and `prooph_service_bus.event_bus.plugin`) or
> - `prooph_service_bus.plugin` to register it for every message bus.
Now we are ready to dispatch our command.

## Access the command bus
## Dispatching the command

Given our configuration
```yaml
# app/config/config.yml
# app/config/config.yml or (flex) config/packages/prooph_service_bus.yaml
prooph_service_bus:
command_buses:
acme_command_bus: ~
```

we can access the command bus from the container using the ID `prooph_service_bus.acme_command_bus`:

```php
<?php
// …
Expand All @@ -163,9 +106,15 @@ class RegisterUserController extends Controller
public function indexAction()
{
// …
$this->get('prooph_service_bus.acme_command_bus')
$this
->get('prooph_service_bus.acme_command_bus')
->dispatch(new RegisterUser(/* … */));
// …
}
}
```

That was everything we need to configure and dispatch our first command.
Perhaps you want to know more about [routing](./routing.html),
about how to customize message buses with [plugins](./plugins.html)
or about what information will be included in the [profiler](./profiler.html)?
80 changes: 80 additions & 0 deletions doc/plugins.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Plugins

Plugins are a great way to expand a message bus with additional functionality.
You can find more information about PSB plugins and a list of included plugins in the
[documentation of the Service Bus](http://docs.getprooph.org/service-bus/plugins.html) itself.

There are two ways to attach a plugin to a bus.
You can configure it using a tag at the plugin definition or directly at the bus configuration.

We will show you the configuration using the example of the
`Prooph\ServiceBus\Plugin\InvokeStrategy\HandleCommandStrategy` – which is part of the PSB –
but de facto each plugin will be attached the same way.

The basis for both ways is the service definition of the plugin:
```yaml
# app/config/services.yml
services:
acme.prooph.plugin.handle_command_strategy:
class: Prooph\ServiceBus\Plugin\InvokeStrategy\HandleCommandStrategy
```
and a configured message bus:
```yaml
# app/config/config.yml or (flex) config/packages/prooph_service_bus.yaml
prooph_service_bus:
command_buses:
acme_command_bus: ~
```
The command bus is used as example again, plugins are attached to each bus the same way.
## Definition using tags
If you don't know about tags in Symfony please have a look at the
[official documentation](http://symfony.com/doc/current/service_container/tags.html).
To attach a plugin to a specific message bus, we just need to add a tag to its service definition:
```yaml
# app/config/services.yml
services:
acme.prooph.plugin.handle_command_strategy:
class: Prooph\ServiceBus\Plugin\InvokeStrategy\HandleCommandStrategy
tags:
- { name: 'prooph_service_bus.acme_command_bus.plugin' }
```
The name of the tag is simple `prooph_service_bus.<name-of-the-bus>.plugin`.
There are no additional attributes that can be set.

But sometimes you want to attach a plugin to more than one message bus, e.g. for logging.
Of course you could add multiple tags, but for two use cases there are special tags:

- To attach the plugin to every command bus, you can use the tag `prooph_service_bus.command_bus.plugin`
(resp. `prooph_service_bus.query_bus.plugin` for every query bus and `prooph_service_bus.event_bus.plugin` for every event bus).
- To attach the plugin to every message bus (no matter whether it is a command bus, a query bus or an event bus)
you can use the tag `prooph_service_bus.plugin`.

That is everything you need to know about attaching plugins to a message bus using tags.

Let's now have a look at the other way.

## Definition at the bus

If you are no fan of service tags, you can attach the plugin directly at the bus configuration:
```yaml
# app/config/config.yml or (flex) config/packages/prooph_service_bus.yaml
prooph_service_bus:
command_buses:
acme_command_bus:
plugins:
- "acme.prooph.plugin.handle_command_strategy"
```
Again this will work the same way for query buses and event buses.

> **Hint:** To get autocompletion in some IDEs you can prepend the service id
> with an `@` (`"@acme.prooph.plugin.handle_command_strategy"`).
>
> The bundle will recognize this and find your plugin anyway.

If you attach your plugins directly at the bus configuration, they will be at a central place.
But there is no way to attach them to every message bus or every message bus of a type like when using tags.
35 changes: 35 additions & 0 deletions doc/profiler.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Symfony Profiler

The ProophServiceBusBundle provides several plugins that help you to inspect your application.
For most of them you will need access to the Symfony Profiler, so please ensure that you have installed the
[WebProfilerBundle](https://packagist.org/packages/symfony/web-profiler-bundle).

## DataCollectorPlugin

The DataCollectorPlugin gathers data about the dispatched messages and shows them in an extra section within
the Symfony Profiler.
There is one profiler for the command- and one for the event-buses
and both are automatically enabled if `kernel.debug` is `true`.

![Example of a timeline with a command and an event](profiler_data_collector_sections.png)

## PsrLoggerPlugin

The PsrLoggerPlugin fills your log with information about your dispatched messages.
There will be one PsrLoggerPlugin automatically registered for each defined message bus.

You can find the logged messages either in the *Logs* section of the Symfony Profiler or directly in your log
(depending on how your logging is configured).

![Example of a timeline with a command and an event](profiler_logs.png)

## StopwatchPlugin

The StopwatchPlugin is automatically enabled if `kernel.debug` is `true`
(which is the case e.g. in the `dev` environment).
It times the execution time of your command- and event-handlers.
The collected data are shown within the *Performance* section of the Symfony Profiler.

For an example with a executed command and an executed event please have a look at the following image:

![Example of a timeline with a command and an event](profiler_timeline.png)
Binary file added doc/profiler_data_collector_sections.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/profiler_logs.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/profiler_timeline.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 8845038

Please sign in to comment.