IsNSFW – Abandoning Commands (CQRS) in favor of ServiceStack services

Today we’ll be looking at this commit.

In my previous article I talked about implementing experimenting with Command-Query Responsibility Segregation (CQRS). When testing the commands directly, it all made sense. But as soon as I started wrapping these commands in my ServiceStack services, things started breaking down. I found I was duplicating a lot or work — not in a DRY way, but just because the different layers had slightly different needs. I wanted my ServiceStack service layer, for example, to take link tags as their string values (e.g. “V” for Violence, “G” for Gore, etc), whereas my commands were dealing directly with data and they could work off their unique identifiers (e.g. 1 for Violence, 2 for Gore, etc).

Instead, what I realized is that I could implement my services in a way that felt a lot like my command handlers in my previous CQRS handlers. ServiceStack implements cross-cutting for me through Request and Response filters, so that was still covered. And ServiceStack’s Gateway and Service Discovery features, I distribute my services (command handlers) however I needed to; microservices anyone?

Let’s compare some things side by side.

Create Link Command / Request

Registering the handler in a command:

Registering the handler in ServiceStack:

The CreateLinkCommand handler implementation:

The ServiceStack service implementation:

The Command’s decorator-based Validator:

The ServiceStack Request Validator:

The code is nearly identical, and that’s why I decided to abandon a separate command layer. Comparing the initial commit of commands to this commit that favors straight services, you’ll see so many parallels that, to me, justify abandoning having a commands layer in my architecture. It was adding a lot of overhead and not a lot of value.

An added bonus by using ServiceStack, the AppHost and plugin architecture does a lot of the auto-wiring for me that I would have had to solve for myself with commands. Cross-cutting in Commands required my Simple Injector implementation to register the cross-cutting decorators. In ServiceStack, it’s just Plugins.Add(…) to add things like validation, logging, authentication, authorization, and anything else you can dream up at the service layer.

Testability

I’m not going to go into detail about how to test things here. I might do a follow-up post later. However, I know that testing and testing “right” is a concern. If this a Unit test or an integration test? The reason I’m not going into it myself is because ServiceStack outlines testing very well in its help documentation. I followed their examples during my own unit test implementations and didn’t find any noteworthy derivations. Still, if you’re new to ServiceStack and/or Unit Testing, I recommend reading over the documentation in the links I provided and check out how I implemented my CreateLinkEventRequest tests.

IsNSFW – Getting Started

This project is really just way for me to experiment with various technologies. Key points:

This is a lot to cover in a single article. But that’s sort of the point I’d like to make. When starting a new project, there are all these concerns that are in the back of our minds. When starting IsNSFW, I was almost paralyzed by thinking about all these concerns at once. What’s my starting framework? What are my settings? What’s my database going to be? How do I do DB migrations? And of course…

Deep breath, Eli… it’ll all be ok. Just have to get started, so that’s what I did. I put down those concerns and started at the most logical point — the beginning! I had to start with initializing my environment.

To do that, I needed to get ServiceStack’s bootstrapper installed.

I ended up choosing the mvc-corefx package. I didn’t want too much generated code because I wanted to really dive in and figure out how things worked.

From there, I took a note out of TDD and started building tests around what I wanted to happen. I admit that I took a bit of a circuitous route to get there. I knew I wanted to implement (practice) certain patterns, like CQRS. I found a series of articles that I liked on the topic, and I’ll be referencing those articles throughout my IsNSFW series (Articles 1, 2, and 3).

You can see the full commit here, but here’s what’s noteworthy:

  • I created ICommand and ICommandHandler interfaces. To satisfy when I needed to at least get the aggregate ID (fancy word in DDD for a top-level model that has an ID) out of my command, I also implemented ICommandWithResult. There’s debate over whether or not this constitutes returning a value, which Commands aren’t supposed to do, but after reading lots of articles, I feel like this is an acceptable use of the pattern. See this StackOverflow thread for more details.
  • I created a CommandHandlerBase which for me contained the bare-minimum needed to handle a command: being able to execute against a DB.
  • I used the decorator pattern to use for “injecting” validation through the ICommandValidator interface.
  • I created my LinkCommandHandlers class that will, in theory, handle all Link-level commands (link being my Aggregate root here). I mention this explicitly because some argue that you shouldn’t have a single class that handles all commands; each command should have its own handler. I get it… but I thoughtfully decided to do it this way instead to be more wrist-friendly.
  • I created my data models for how I anticipated saving them to the DB. I used ServiceStack ORMLite. Example: Link.
  • I created a framework for repositories and split out the interfaces from the implementations. Example: ILinkRepository and its implementation LinkRepository.
  • I created my first command for Create Link and its validator and its initial test cases.

I just yadda-yadda’d over a lot of things. I tried to give links to take a deeper look at the code and also links to show where I did my research for getting started. But in the end, I did all of the above to create a framework that would support the simplicity of this code below:

For me, the elegance of CQRS is in the above Handler method. It’s so succinct. It doesn’t do anything fancy. It doesn’t even do validation! It has a single job (SOLID!) to do. All other cross-cutting concerns, such as validation, authentication, and authorization, will have been handled by the time this code gets called. I don’t even have to be concerned with how my application will know to call that handler! That’s some other process’s job that gets wired up later.

Testing is just as straight forward:

My only complaint (against myself) is that my GetCommandHandler method decorates the command handler with the validator. That’s a mistake, and a bad unit test. In hindsight, I was overly eager to figure out how it all fit together. It was unnecessary to test the decorated version, considering I have my own set of tests off to the side that test the CreateLinkCommandValidator. I end up with some duplicate tests. But still… so cool to see it in action and for everything to be so compact!

Speaking of the CreateLinkCommandValidator, I think it’s also worth pointing out its implementation (which relies on ServiceStack’s validation classes at its core):

The rules at the top are pretty basic. I added a custom MustBeAUrl rule, which can also be found in this commit, but otherwise it’s nothing special. What was a real A-HA! moment for me was the extended validation that makes use of the repository to check if that link key already exists. In the past, I’ve used just basic validation implementations, relying on “bigger” validation (like key already exists) checks to happen in my service implementation later. I had never thought about injecting a repository like this, mostly because I use ServiceStack’s validation which can be used simultaneously as frontend validation and backend service validation; the frontend doesn’t have direct access to the repositories, so there was no way to inject that dependency there. However, having a backend-only command object gave me the freedom to make my validator more robust. In fact, the decorator pattern required me to implement it this way. If there’s nothing that sits between my command handler and the command actually being handled and thus having data stored in the DB, I had to get the job done with a decorator. Validation seemed like the obvious choice.

Conclusions

It’s a single commit, but it took a lot of tinkering and tweaking to get to where I was happy with it. I relied heavily on the articles I mentioned above and I tried to stick to the patterns as much as possible. Overall, I’m happy with the outcome.

With that said, one thing I don’t love about this implementation is that the command handler has to know about the DB directly; that is, it directly uses a DB connection. Should I abstract that way into a repository? I’m leaning towards yes. Many examples I see have commands working directly with the DB, with only the Query side of CQS working with a repository. I don’t know if that’s a consequence of trying to be brief because they’re showing an example or if that’s how it works. For example, maybe it’s ok that my command object works with the DB since the command object has only one, single responsibility: to take something and save it to the DB. I would argue that what my command object is doing is actually two things: translating the command into my Domain Model (i.e. what I save to the DB); and doing the actual saving. Are these things two sides of the same coin? Is it ok that my command is doing this much work? We’ll see…

Hello World! – IsNSFW Edition

Back in 2009, I launched a service called IsNSFW (Is Not Safe For Work). It was a URL shortener that allowed the sharer to tag a link as NSFW, so when the user clicks the link they get a warning and a chance to turn back.

The need arose from the services like twitter where character real-estate was in short supply and everyone started turning to URL shorteners like bit.ly.

That was all fine and dandy, except the end user never knew what was behind that beautifully-short URL. That’s a problem!

So… IsNSFW was born!

We enjoyed some online success. We had quite a few articles written about us. Some in Italian; some in Russian; some in Spanish; some in French; some in languages we didn’t even know.

And then… catastrophe!

Our CC lapsed on our hosting provider and we didn’t know it. They have a pretty strict policy. They don’t just turn off your account — they delete it!

Our database was gone, and I didn’t have the energy to try to rebuild the hype and following.

until now!

I wanted to play around with some new tech and design patterns. I didn’t want to just fake through it with some sample projects from the web; and I didn’t want to dive in with one of my “this is gonna make me millions!” ideas*. So, I settled on IsNSFW.

Over the next (insert estimated post count here) posts, I’ll be taking you through a series of commits and explain what I did and why. I’ll be doing this for a few reasons:

  1. I feel like a lot of articles I read jump in to the middle and getting started can be tough. So I want to try my hand at explaining things and see if I can help others.
  2. While my goal is to tackle specific technology and design patterns, I might not have done it the best way! I’m not perfect. I’m hoping that by sharing my story, in addition to helping others, I hope others help me! Iron sharpens iron, my friends.
  3. Lastly, I’m going to be writing these blog posts to keep myself accountable. I want to keep things moving, but I don’t want to move so quickly that I’m neglecting the real purpose of the project — to learn! By “Stepping Back” (hah!) from the keyboard and really planning things out, I’m hoping for better results and more consistency.

IsNSFW is available on github. Feel free to play around with it. And as always, suggestions and comments are more than welcome!

* Actual amount of “millions” being generated may vary.