Saturday, September 5, 2015

Learning The Clean Architecture and Applying it While Doing BDD

The Clean Architecture



Uncle Bob Martin's Clean Architecture is one that I am aspiring to model my applications and Services by currently.


I realized that after thinking about it, when I was pairing with a couple 8th light guys in the past at a previous company, that they were implementing some of the Clean Architecture in our Web Service code.  At the time, I was not aware of the Clean Architecture Model (Onion).  I was defintely aware of creating layers and did create layers such as Repository, Business Objects, and all that.


But I realized that how I was doing that prior, wasn't quite clean.


So I am suggesting that if you really wanna build your architecture in a very simple and decoupled manor, I'm advocating The Clean Architecture model.  It very much mirrors the Hexagonal Architecture Model.


So if you would like to venture off learning more about it, then I suggest going about it in a certain fashion, and to go through these resources in a specific order below.  This order really helped me understand Applying the Clean Architecture (patterns, layers, etc.) along with incorporating that while you TDD the actual implementation.


Here's the order I suggest (my prescription).  There is specific content in here that piggies on one another.


Make these worth your while:

  • Set aside true quiet time away from kids or whatever..in your man cave if you have one
  • Watch each video in full.  Yes unfortunately this takes time and dedication.  Take a Saturday to do it, do it at night for 2-3 hours;...whatever you have to do to find time to watch each of these in full.  If you wanna learn, you gotta sacrifice.  But these resources are truly great ones below, you won't be sorry
  • Concentrate.  Listen to everything said very carefully, and definitely take notes..I always go back to my notes, I don't wanna re-watch it 100 times because I forgot everything
  • It'll take you weeks to get through all these but seriously watch them all, again the order here is important

First, Understand Clean Architecture



Then Understand Hexagonal Architecture 

  • The watch Decoupling from ASP.NET - Hexagonal Architectures in .NET - nevermind that this is titled .NET, Ian keeps things applicable and terms are not really geared toward .NET so this is a good watch for anyone .NET or not
    • A deep dive into truly understanding Hexagonal.  And Ian explains it like no other

Then Understand Keeping Things Simple

  • Then watch Rails Conf 2012 Keynote: Simplicity Matters by Rich Hickey
  • Then watch Keynote: 8 Lines of Code - which talks about how you really keep code simple, and the fact that you do not need to always use frameworks which can actually make things more complicated or totally unnecessary if you design your code in very small modulars.  (BTW, This is also is a big reason why I left .NET.  Microsoft pushes shitty frameworks, horrible xml driven frameworks, and more garbage down your throat when you just need simple, clean, decoupled code which means you end up not needing all those heavy frameworks Microsoft tries to push down your throat)
  • Then read Corey Haines's book 4 Rules of Simple Design 

Finally Get into the BDD 

This will apply some of what you learned above to actual code.

After you've watched and read the previous section, now is the time to understand proper BDD and applying the concepts above.



    Optional but a good Resource for later when you have time after all the above: Start Doing Real World TDD Now!.  This blog is by Eric Smith.  He's a developer I had the privilege to pair program a bit from 8th light, and he runs their training program at 8th Light, their Apprentice program.  

    I probably learned more in 5 months with Eric and another 8th Light Consultant that would have taken me 2 years to learn.  Honestly while the list above is awesome, the best way to learn BDD IMO is to pair with seasoned TDD'ists.  Get 8th Light to come into your company for a few months, year, whatever.  The benefits are exponential for your team and your company as I have experienced myself with these guys.

    Yes this is a lot to read up on and watch but I guarantee it'll help bridge the gap much sooner.

    Hoping this helps others as it has helped me bridge the gap with Clean Architecture, Hexagonal, Ports, Adapters, and how to approach this and separate this while doing test driven.

    Thursday, September 3, 2015

    Testing the Koa.js Response Context through koa-controller


    Today I was test driving some new endpoints for my Node.js REST API.  I decide it was time to add koa-controller so that I could manage routes better and also map them to controller actions.

    koa.js

    I'm using koa.js for building out our new REST API in Node.js.

    koa uses generator functions.  When you create a koa route, like anything, you can grab the request context and set the response context.

    koa-controller

    koa-controller adds in support for matching routes with controllers and actions.

    A koa-controller receives the koa request context and then in your controller action, you can process the context.  And then set the context's response data, etc which koa uses to send back the http response.

    With this middleware, I had created an initial action function as so in my controller:

    (I apologize for shitty blogger and the lack of formatting below.  I'm working on moving this blog to some other platform)

    module.exports = {
        find: function *(){
            var response = this;
            response.statusCode = 200;

            _gateway.find(function(foundData){
                if(!foundData || Object.keys(foundData).length === 0){
                    response.body = null;
                    response.statusCode = 204;
                }

                response.body = foundData;
            });
        }
    };

    problem is, how can my test get back the koa context to test whether my controller did what it was supposed to?  Right now, koa-controller passes back the context automatically.  But I wanna catch it for testing in my unit tests.

    You can't just do a return response and we want to keep our functions async anyway and use callbacks (ideally promises) along with generators not because "it's cool"...but because it's necessary and also required by koa in the first place to be using generators for this.

    Technically I should mock the koa context because I'm not testing koa; I wanna be testing  the logic I wrote in my controller only.  That'll be next.  But I wanted to figure out how I'd get the context back regardless first.

    Generator Functions Save the Day

    Since my action function has to be a generator function for koa-controller, that means I could use yield to return the context if I'd like.

    That also meant making my callback function a generator or else this wasn't gonna work.

    So here it is with yield and the callback generator function

    module.exports = {
        find: function *(){
            var response = this;
            response.statusCode = 200;

            _gateway.find(function*(foundData){
                if(!foundData || Object.keys(foundData).length === 0){
                    response.body = null;
                    response.statusCode = 204;
                }

                response.body = foundData;

                yield Object.create(response);
            });
        }
    };

    notice I simply added * to _gateway.find's callback function.

    Now you're probably wondering why I created another object here instead of just doing a yield response; 

    Well koa-controller is handling returning the koa context so when I tried that, it was conflicting with koa-controller core code.  

    So what I had to do is simply clone the context and return it.  Now it's independent of whatever process was handling the real context prior to this.

    My Mocha.js Test

    I use mocha.js for my BDD.

    So now I can can test the context's values that came back from the controller's find action function:

    it('should return no country when no country exists', function(done){
        var countries = {};
        countryMockGateway.setCountries(countries);
        countryController.gateway(countryMockGateway);

        var koaResponseContext = countryController.find().next().value;

        should.not.exist(koaResponseContext.body);
        koaResponseContext.statusCode.should.equal(204);
        done();
    });

    ES5

    With ES5, you can easily clone which was very hard to do prior with simply Object.create().

    So the next time your architect tells you "We don't need to be using new stuff like ES6, that's overboard", you can tell him he's full of garbage.  I didn't have an architect who did that where I"m working but I have in the past.  So here's a good use case for testing and using generators and cloning to easily accomplish what would have probably been a tangled mess of code to do the same thing prior to ES5.