Refactoring the Cat API client - Part III
In the first and second part of this series we’ve been doing quite a bit of work to separate concerns that were once all combined into one function.
The major “players” in the field have been identified: there is an HttpClient
and a Cache
, used by different implementations of CatApi
to form a testable, performing client of The Cat Api.
Representing data
We have been looking at behavior, and the overall structure of the code. But we didn’t yet look at the data that is being passed around. Currently everything is a string, including the return value of CatApi::getRandomImage()
. When calling the method on an instance we are “guaranteed” to retrieve a string. I say “guaranteed” since PHP would allow anything to be returned, an object, a resource, an array, etc. Though in the case of RealCatApi::getRandomImage()
we can be sure that it is a string, because we explicitly cast the return value to a string, we can’t be sure it will be useful to the caller of this function. It might be an empty string, or a string that doesn’t contain a URL, like 'I am not a URL'
.
Refactoring the Cat API client - Part II
The world is not a safe thing to depend upon
When you’re running unit tests, you don’t want the world itself to be involved. Executing actual database queries, making actual HTTP requests, writing actual files, none of this is desirable: it will make your tests very slow as well as unpredictable. If the server you’re sending requests to is down, or responds in unexpected ways, your unit test will fail for the wrong reasons. A unit test should only fail if your code doesn’t do what it’s supposed to do.
Refactoring the Cat API client - Part I
Some time ago I tweeted this:
I didn't mention this yet, but I'm working on a series of videos about the subject matter of my Principles of Package Design book.
— Matthias Noback (@matthiasnoback) May 14, 2015
It turned out, creating a video tutorial isn’t working well for me. I really like writing, and speaking in public, but I’m not very happy about recording videos. I almost never watch videos myself as well, so… the video tutorial I was talking about won’t be there. Sorry!
Experimenting with Broadway
Event sourcing with Broadway
At the Dutch PHP Conference I attended a workshop by Beau Simensen and Willem-Jan Zijderveld. They showed us some examples of how to work with Broadway, a framework for event sourcing, with full Symfony integration, created by the smart people at Qandidate.
During my two weeks of funemployment, before starting my new job at Ibuildings, I decided to recreate one of my previous projects using Broadway. As it turns out, it’s a great framework that’s quite easy to use and is very powerful at the same time. Even though it’s not a stable package (as in, it’s still in the 0.x
version range), I think it’s safe to depend on it.
Introducing the SymfonyBundlePlugins package
Bundles, not extensible
A (Symfony) bundle usually contains just some service definition files as well as some configuration options which allow the user of that bundle to configure its behavior (e.g. provide server credentials, etc.). Bundle maintainers usually end up combining lots of these options in one bundle, because they all belong to the same general concept. For example, the NelmioSecurityBundle contains several features which are all related to security, but are code-wise completely unrelated. This means that this one package could have easily been split into several packages. Please note that I’m not making fun of this bundle, nor criticizing it, I’m just taking it as a nice example here. Besides, I’ve created many bundles like this myself.
Compartmentalization in the PHP community
The PHP community
I’m a proud member of the PHP community. Recently I’ve come to realize though that “the PHP community” is a very complicated thing, and in fact, not even one thing.
I consider it part of my “job” to keep track of what’s going on in the community and I consider Twitter to be the proper place to look for news from the community, as well as a great place to check in on the pulse of the community. What are people happy about, what are people looking at, who are they trolling? This is all fascinating to me.
Lean publishing "Principles of Package Design"
During the great PHP Benelux Conference 2015 edition I published the final version of Principles of Package Design. Let me tell you a little bit about its history and some of the things I had to deal with.
A bit of history
My first book, A Year With Symfony, was released on September 4th, 2013. Just 6 days later, I started working on Principles of PHP Package Design. As it turned out, it was quite hard to keep the process going. There were several months in which I wrote nothing at all. Sometimes I picked up the work, but then I had completely lost my track and tried to get back on it by revising existing chapters over and over again. Meanwhile all kinds of other projects begged for attention as well, including the release of the backend project of the new nos.nl website, the preparations for the Hexagonal architecture training and the birth of our daughter Julia ;)
Collecting events and the event dispatching command bus
It was quite a ride so far. We have seen commands, command buses, events and event buses. We distilled some more knowledge about them while formulating answers to some interesting questions from readers.
Why you should not dispatch events while handling a command
In a previous post we discussed a sample event (the UserSignedUp
event):
class UserSignedUp implements Event
{
public function name()
{
return 'user_signed_up';
}
public function __construct($userId)
{
$this->userId = $userId;
}
public function userId()
{
return $this->userId;
}
}
An instance of such an event can be handed over to the event bus. It will look for any number of event handlers that
wants to be notified about the event. In the case of the UserSignedUp
event, one of the interested event handlers is
the SendWelcomeMailWhenUserSignedUp
handler:
Some questions about the command bus
So far we’ve had three posts in this series about commands, events and their corresponding buses and handlers:
Now I’d like to take the time to answer some of the very interesting questions that by readers.
The difference between commands and events
Robert asked:
[…], could you possibly explain what are the main differences between a command bus and an even dispatcher?
From commands to events
In the previous posts we looked at commands and the command bus. Commands are simple objects which express a user’s intention to change something. Internally, the command object is handed over to the command bus, which performs the change that has been requested. While it eventually delegates this task to a dedicated command handler, it also takes care of several other things, like wrapping the command execution in a database transaction and protecting the original order of commands.