Monday, June 30, 2014

How to Unit Test a Sails.js Model Without Lifting Sails

The Problem

As a quick follow-up to the previous post about creating a traditional MVC-style Web API using Sails.js, I did get some questions around how to test models in Sails, especially those that have instance methods and override their Waterline lifecycle callbacks, such as afterCreate and afterUpdate.  This post is for you guys!


Friday, June 20, 2014

Growing Up and Growing Large: Modern JavaScript Web Development Using Sails.js and AngularJS (Part 2 of 3)

Sails.js: A Server-side Solution

One of the early criticisms (and also strengths) of JavaScript, and open source architectures in general, was the conundrum of "too many options".  After all, it was scientifically proven that people (yes, even software developers) prefer solutions over individual components.  Part of growing up is learning from past mistakes, and the JavaScript community has responded in kind, particularly the folks at Giant Squid with Sails.js.

Sails.js attempts to reel in the noise in choosing components for a server-side JavaScript framework.  It is a proper MVC framework, inspired by Ruby on Rails, that gives a developer everything you could possibly need: an MVC pattern, ORM, multiple adapters for data stores, Socket.io support, intelligent routing, and much more, all in a carefully curated solution so that a developer can focus on making great software products versus worrying about getting components to play nicely with each other.


Sunday, June 15, 2014

Seeding a Sails.js Application's MongoDB Store Standalone Using Node.js and Waterline

As I was constructing the Sails.js application for the forthcoming Part 2 of my 3-part MEAN-stack series, I realized that I needed an easy way to seed the MongoDB instance on which my Sails app would run.  In this particular example, I wanted to seed three collections (Movie, Person, and MoviePerson) in MongoDB with data defined in .json files that matched the Models for these collections I'd created in Sails.

So, how do we go about doing this in a standalone fashion using Node.js and Sails' excellent Waterline ORM?

Thursday, June 12, 2014

Growing Up and Growing Large: Modern JavaScript Web Development Using Sails.js and AngularJS (Part 1 of 3)

The JavaScript Revolution

I will be the first to admit: had you told me that JavaScript would become the de-facto standard for web development a few years ago, I would've laughed in your face and requested that you take some breathalyzer measurements.  How could a language reserved for some ugly client-side DOM manipulation and the general clutter of the view-side of MVC architectures become anything close to enterprise-grade?  Heck, JavaScript was even an afterthought, built in 10 days by Brendan Eich to give browsers some whizbang on the client-side.

Well, the numbers don't lie: JavaScript development has grown up and grown large...but this ain't your mid-to-late 2000's JavaScript, folks.  We are talking highly scalable, testable, and standards-compliant multi-platform development.  We are talking a language that is very well suited for using NoSQL data stores.  We are talking a language that empowers developers to react and implement quickly.  Modern JavaScript is to past JavaScript as a jetliner is to the Wright Brothers plane.  It is time to take it seriously and for practitioners of classical languages to bone up on this quirky but highly effective interpreted language and its frameworks.

Lean and MEAN

PHP had the LAMP stack (Linux/Apache/MySQL/PHP).  JavaScript has the MEAN stack (MongoDB/Express/AngularJS/Node.js).  Like with the LAMP stack, each letter of the acronym represents important components.

"M": MongoDB

MongoDB is the data store of choice for JavaScript-based frameworks.  It is, indeed, a NoSQL database: a schemaless document store that, out of the gate, supports REST and JSON, as well as scale-out capabilities (sharding) that you can expect from a NoSQL platform.

"E": Express

Express is a Node.js-based framework (Node.js is, incidentally enough, also part of the overall stack) that represents server-side JavaScript.  Yes, server-side like ASP .Net MVC and Spring MVC.  This is the Server API portion of a MEAN stack application, the keeper of domain objects via RESTful endpoints.

Sails.js is an excellent MVC framework built on top of Express, and is the framework we will use for this thought exercise.  For .Net folks, think of Express as IIS and Sails.js as ASP .Net MVC.  For Java folks, think of Express as JBoss and Sails.js as Spring MVC.  You could technically build a "traditional" server-side web application on Express without the use of Sails, if you so desired.

"A": AngularJS

AngularJS is a client-side single page application (SPA) framework heavily sponsored by Google that aims to "extend" HTML to represent the dynamic nature of web applications and provide a slick, seamless user experience.

"N": Node.js

While technically a subset of the "E" part of MEAN, Node.js does so much more than just the server-side operations.  Node.js helps manage JavaScript library dependencies for the Server API as well as AngularJS (using NPM...think Maven for Java or NuGet for .Net).  It can also help streamline the "build" workflow of a MEAN stack application by running unit tests (in conjunction with a task runner, like Grunt or Gulp).  Node.js is essentially the glue that binds all the elements together.

A Typical MEAN Stack Web Application

A "typical" use case of a web application

As the diagram above indicates, MEAN stack applications give your typically nice, segregated separation of concerns.  

Sails.js on the server-side exposes RESTful endpoints for external applications to interact with the domain of the application.  The domain is persisted on MongoDB and you'll have "POJSO's" (Plain-old JavaScript Objects) for Sails.js to interact with the persistence layer.  In case you're wondering, yes, you could easily swap out MongoDB with MySQL or PostgreSQL if you're still unsure about NoSQL platforms...but I'd recommend against torturing yourself in that fashion.  ;)

AngularJS on the client-side focuses on a rich user experience, shuttling any of its data needs to the Sails.js Server API.  Likewise, if you were to build, say, a native Android or iOS application, they would interact directly with the Sails.js Server API to get at your application's domain object model.  True multi-platform development!

While the representation above isn't anything new in software, doing a full MEAN stack offers many benefits:
  1. JavaScript end-to-end.  No context-switching for developers when they cross the boundary from client to server-side.  (Read: faster development, real collaboration between client and server)
  2. Built to scale out.  AngularJS is a SPA loaded on the client.  Sails.js runs on Express and Node.js which was designed to scale out.  Likewise for MongoDB.
  3. JavaScript has grown up.  This ain't your daddy's JavaScript.  Want complex collection or object manipulation?  npm install underscore (or lodash).  Need an ORM, Socket.io support, native RESTful/JSON support?  Comes out of the box with Sails.js and AngularJS.  Dependency Injection?  Built into AngularJS, and use require on Sails.js.  Unit testing and mocking: do you prefer jasmine or mocha?

Okay, So Let's Build Something!

In Part 2 of this 3 part series, we're going to get started with a bottom-up approach.  Using Sails.js and MongoDB, we will create a domain model and persistence layer for a movie application called the AgileMovieDB.