Lesson 4: Metadata and Method Invocation

PHP Metadata and Method Invocation

Not having code for Lesson 4? git checkout lesson-4

Metadata

Message can contain of Metadata. Metadata is just additional information stored along side to the Message's payload. It may contain things like currentUser, timestamp, contentType, messageId.

In Ecotone headers and metadata means the same. Those terms will be used interchangeably.

To test out Metadata, let's assume we just got new requirement for our Products in Shopping System.:

User who registered the product, should be able to change it's price.

Let's start by adding ChangePriceCommand

namespace App\Domain\Product;

class ChangePriceCommand
{
    private int $productId;

    private Cost $cost;

    public function getProductId() : int
    {
        return $this->productId;
    }

    public function getCost() : Cost
    {
        return $this->cost;
    }
}

We will handle this Command in a minute. Let's first add user information for registering the product. We will do it, using Metadata. Let's get back to our Testing Class EcotoneQuickstart and add 4th argument to our CommandBus call.

sendWithRouting accepts 4th argument, which is associative array. Whatever we will place in here, will be available during message handling for us - This actually our Metadata. It's super simple to pass new Headers, it's matter of adding another key to the array. Now we can change our Product aggregate:

We have added second parameter $metadata to our CommandHandler. Ecotone read parameters and evaluate what should be injected. We will see soon, how can we take control of this process. We can add changePrice method now to our Aggregate:

And let's call it with incorrect userId and see, if we get the exception.

Method Invocation

We have been just informed, that customers are registering new products in our system, which should not be a case. Therefore our next requirement is:

Only administrator should be allowed to register new Product

Let's create simple UserService which will tell us, if specific user is administrator. In our testing scenario we will suppose, that only user with id of 1 is administrator.

Now we need to think where we should call our UserService. The good place for it, would not allow for any invocation of product.register command without being administrator, otherwise our constraint may be bypassed. Ecotone does allow for auto-wire like injection for endpoints. All services registered in Depedency Container are available.

Great, there is no way to bypass the constraint now. The isAdmin constraint must be satisfied in order to register new product. Let's correct our testing class.

Injecting arguments

Ecotone inject arguments based on Parameter Converters. Parameter converters , tells Ecotone how to resolve specific parameter and what kind of argument it is expecting. The one used for injecting services like UserService is Reference parameter converter. Let's see how could we use it in our product.register command handler.

Let's suppose UserService is registered under user-service in Dependency Container. Then we would need to set up the CommandHandlerlike below.

Reference- Does inject service from Dependency Container. If referenceName, which is name of the service in the container is not given, then it will take the class name as default.

Payload - Does inject payload of the message. In our case it will be the command itself

Headers - Does inject all headers as array.

Header - Does inject single header from the message. There is more to be said about this, but at this very moment, it will be enough for us to know that such possibility exists in order to continue. You may read more detailed description in Method Invocation section. \

Default Converters

Ecotone, if parameter converters are not passed provides default converters. First parameter is always Payload. The second parameter, if is array then Headers converter is taken, otherwise if class type hint is provided for parameter, then Reference converter is picked. If we would want to manually configure parameters for product.register Command Handler, then it would look like this:

We could also inject specific header and let Ecotone convert it directly to specific object (if we have Converter registered):

Last updated

Was this helpful?