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

This entry is part 3 of 3 in the series IsNSFW

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.

Series Navigation<< IsNSFW – Getting Started