Message Endpoint PHP
Message Endpoints/Handlers are consumers and producers of messages. Consumer are not necessary asynchronous, as you may build synchronous flow, compound of multiple endpoints. You will not have to implement them directly, as you should not even have to build messages and invoke or receive message directly from the Message channel. Instead you will be able to focus on your specific domain model with with an implementation based on plain PHP objects. By providing declarative configuration, you can "connect” your domain-specific code to the messaging infrastructure provided by Ecotone.
All Message Handlers follows simple low level interface
interface MessageHandler
{
/**
* Handles given message
*/
public function handle(Message $message): void;
}
Service Activator PHP
The Internal Handler connecting any service available in Depedency Container to an input channel so that it may play the role of a Endpoint. If the service produces output, it may also be connected to an output channel.
class Shop
{
#[InternalHandler("buyProduct")]
public function buyProduct(int $productId) : void
{
echo "Product with id {$productId} was bought";
}
}endpointId - Endpoint identifier
inputChannnelName - Required option, defines to which channel endpoint should be connected
outputChannelName - Channel where result of method invocation will be
requiredInterceptorNames - List of interceptor names, which should intercept the endpoint
Splitter PHP
The Splitter is endpoint where message can be splitted in several parts and be sent to be processed indepedently.
class Shop
{
#[Splitter(inputChannelName="buyProduct", outputChannelName="buySingleProduct")]
public function sendMultipleOrders(array $products) : array
{
return $products;
}
#[ServiceActivator("buySingleProduct")]
public function buyProduct(string $productName) : void
{
echo "Product {$productName} was bought";
}
}endpointId - Endpoint identifier
inputChannnelName - Required option, defines to which channel endpoint should be connected
outputChannelName - Channel where result of method invocation will be
requiredInterceptorNames - List of names, which should intercept the endpoint
Message Router PHP
Routers consume messages from a message channel and forward each consumed message to one or more different message channels depending on a defined conditions.
Router must return name of the channel, where the message should be routed too. It can be array of channel names, if there are more.
class OrderRouter
{
#[Router("make.order")]
public function orderSpecificType(string $orderType) : string
{
return $orderType === 'coffee' ? "orderInCoffeeShop" : "orderInGeneralShop";
}
}endpointId - Endpoint identifier
inputChannnelName - Required option, defines to which channel endpoint should be connected
isResolutionRequired - If true, will throw exception if there was no channel name returned
Router is powerful concept that is backing up Query/Command and Event Bus implementations. Together with , you may roll up your own Bus implementation or build workflow pipelines.
class OrderRouter
{
#[Router("order.bought")]
public function distribute(string $order) : array
{
// list of Channel names to distribute Message too
return [
'audit.store',
'notification.send',
'order.close'
];
}
}interface QueryGateway
{
#[MessageGateway("query.router")]
public function query(string $queryEndpoint): string;
}
final class QueryService
{
#[Router("query.router")]
public function getQuery(string $shopName): string
{
return sprintf("query-%s-shop", $shopName);
}
}
final class ShopQueryHandler
{
#[QueryHandler("query-coffee-shop")]
public function queryOne(): string
{
return "coffee";
}
// We are routing directly to given channel name, so we use lower level abstraction ServiceActivator
// The benefit of it is, that endpoint is actually hidden and can not be called directly from QueryBus.
#[ServiceActivator("query-milk-shop")]
public function queryTwo(): string
{
return "milk";
}
}