webspot / messagebus
Webspot MessageBus
Installs: 136
Dependents: 0
Suggesters: 0
Security: 0
Watchers: 1
Open Issues: 0
pkg:composer/webspot/messagebus
Requires
- php: >=5.4.0
- webspot/api: >=0.9.5,<2.0.0
Requires (Dev)
- codeclimate/php-test-reporter: dev-master
This package is not auto-updated.
Last update: 2015-12-07 13:06:50 UTC
README
Inspired by MessageRequest-Oriented Middleware, though not implementing its asynchronous nature.
The idea is to decouple application layers by not having their classes interact with each other directly. Instead they get a MessageBus which they ask to respond to a RequestMessage.
The RequestMessage
A RequestMessage is an immutable object describing what the client expects. This means that any request data must be
passed through the constructor. A RequestMessageInterface implementation consists of the following methods:
- getName() : string returns a unique string identifying the request
- getRequestData() : array returns the requests data serialized into an array
Other getters may be defined upon the RequestMessage to allow working with non-array-serialized data. Any method changing the message must return a new instance with the change instead of changing the object.
The ResponseMessage
A ResponseMessage is an immutable object describing the server's response to a request. This means that any response
data must be passed through the constructor. A ResponseMessageInterface implementation consists of the following
methods:
- getRequestName() : string returns a unique string identifying the request
- getResponseData() : array returns the response data serialized into an array
Other getters may be defined upon the ResponseMessage to allow working with non-array-serialized data. Any method changing the message must return a new instance with the change instead of changing the object.
The MessageBus
The MessageBus consists of a Protocol object and an implementation of the
MessageBusInterface::handle(RequestMessageInterface $message) : void method. The handle() method will throw an
UnhandledMessageException the MessageRequest didn't generate a Response.
An example
Let's say we're in a Controller and want to fetch an Entity. This might look like this:
<?php
namespace Application\Controller;
use Webspot\MessageBus\MessageRequest;
use Webspot\MessageBus\MessageBusInterface;
class PostsController
{
/** @var MessageBusInterface */
private $messageBus;
public function __construct(MessageBusInterface $messageBus)
{
$this->messageBus = $messageBus;
}
public function getAction($id)
{
// Assume we have an extension of the RequestMessageInterface which adds a getEntity() method
$message = new FindEntityMessage('posts.find', $id);
$response = $this->serviceBus->handle($message);
return new JsonResponse($response->getResponseData());
}
public function getCommentsAction($postId)
{
// Assume we have an extension of the RequestMessageInterface which adds a getEntities() method
$message = new GetEntitiesMessage('posts.comments.get', $postId);
$response = $this->serviceBus->handle($message);
return new JsonResponse($message->getCommentCollection()->toArray());
}
}
The Model layer would define HandlerProviders extending the Webspot\MessageBus\HandlerProviderInterface. For the
above use-case a PostsHandlerProvider would provide Handlers extending the Webspot\MessageBus\HandlerInterface
accepting the posts.find and posts.comments.get request messages.
As such the Model layer's MessageBus construction would look somewhat like the following:
<?php use Symfony\Component\EventDispatcher\EventDispatcher; use Webspot\EventManager\EventManager; use Webspot\MessageBus\MessageBus; use Webspot\MessageBus\Protocol; $messageBus = new MessageBus(); $postsHandlerProvider = new PostsHandlerProvider($postsRepository); $messageBus->register($postsHandlerProvider);
We could even take it a step further and even push the HttpResponse generation through another MessageBus:
<?php
namespace Application\Controller;
use Webspot\MessageBus\MessageBusInterface;
class PostsController
{
/** @var MessageBusInterface */
private $serviceBus;
/** @var MessageBusInterface */
private $viewBus;
public function __construct(MessageBusInterface $serviceBus, MessageBusInterface $viewBus)
{
$this->serviceBus = $serviceBus;
$this->viewBus = $viewBus;
}
public function getAction($id)
{
// Assume we receive an extension of the ResponseMessageInterface which adds a getEntity() method
$serviceRequest = new FindEntityMessage('posts.find', $id);
$serviceResponse = $this->serviceBus->handle($serviceRequest);
// Assume we receive an extension of the ResponseMessageInterface which adds a getHttpResponse() method
$viewRequest = new PrepareResponseMessage('posts.view.json', $serviceResponse->getEntity());
$viewResponse = $this->viewBus->handle($viewRequest);
return $viewResponse->getResponse();
}
}
Where the ViewBus would for example have a service using a Fractal\Transformer to transform a Post Entity into an
array and wrap it into a HttpFoundation JsonResponse object.