IsNSFW – Getting Started

This entry is part 2 of 2 in the series IsNSFW

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…

Series Navigation<< Hello World! – IsNSFW Edition