Components Are (Still) Hard on the Web

matryoshka_dolls_3671820040_2

Here’s Johnny! I know, I know. It’s been a while I posted something. In my defence, I was busy gathering real world experience – the kind that allows me to forget the imposter syndrome for a while. We have been busy shipping a complex microservice system, allowing me to test a number of my blog posts in real life. Most are holding up pretty well, thank you very much. However, one thing that continues to bother me is that writing reusable components is still maddeningly hard on the Web in 2016.

Framing the problem

First, let’s define the problem. In a Web app of a sufficient complexity, there will be a number of components that you would want to reuse. You already know we are a large Node.js shop – reusing modules via NPM is second nature to us. It would be so nice to be able to npm install a Web component and just put it in your app. In fact, we do exactly that with React components. Alas, it is much harder once you leave the React world.

First of all, let’s define what ‘reusing a Web component’ would mean:

  1. You can put a component written by somebody else somewhere on your page.
  2. The component will work well and will not do something nasty.
  3. The component will not look out of place in your particular design.
  4. You will know what is happening inside the component, and will be able to react to its lifecycle.

First pick a buffet

Component (or widget) reuse was for the longest time a staple of desktop UI development. You bought into the component model by using the particular widget toolkit. That is not a big deal on Windows or MacOs – you have no choice if you want to make native applications. The same applies to native mobile development. However, on the Web there is no single component model. Beyond components that are intrinsic part of HTML, in order to create custom components you need to buy into one of the popular Web frameworks first. You need to pick the proverbial buffet first before you can sample from it.

In 2016, the key battle is currently between abstracting out and embracing the Web Platform. You can abstract the platform (HTML, CSS, DOM) using JavaScript. This is the approach used by React (and my team by extension). Alternatively, you can embrace the platform and use HTML as your base (what Web Components, Polymer and perhaps Angular 2 propose). You cannot mix and match – you need to pick your approach first.

OK, I lied. You CAN mix and match, but it becomes awkward and heavy. React abstracts out HTML but if you use a custom component instead of the built-in HTML, React will work fine. All the React traits (diff-ing the two incremental iterations of virtual DOM, then applying the difference to the actual DOM) works for custom components as well. Therefore, it is fine to slip in a Web Component into a React app.

The opposite does not really work well – consuming a React component in Angular or Polymer is awkward and not worth it really. Not that the original direction is worth it necessarily – you need to load Web Components JavaScript AND React JavaScript.

Don’t eat the poison mushroom

One of the ways people loaded components in their pages in the past was by using good old iframes. Think what you will about them, but you could really lock the components down that way. If you load a component into your own DOM, you need to really trust it. Single origin policy and CORS are supposed to help you prevent a component leaking data from your page to the mother ship. Nevertheless, particularly when it comes to more complex components, it pays to know what they are doing, go through the source code etc. This is where open source really helps – don’t load a black box component into your DOM.

The shoes don’t match the belt

One of the most complex problems to deal with when consuming a Web component of any type is the design. When you are working in a native SDK, the look and feel of the component is defined by the underlying toolkit. All iOS components have the ‘right’ look and feel out of the box when you consume them. However, Web apps have their own themes that create combinatorial explosion. A reusable component needs to do one of the following things:

  1. Be configurable and themeable so that you can either set a few parameters to better blend it into your style guide, or provide entire template to really dial it in
  2. Be generic and inoffensive enough to be equidistant from any parent theme
  3. Be instantly recognizable (think youtube player) in a way that makes it OK that it has its own look and feel.

A very complex reusable component with a number of elements can be very hard to dial in visually by consumers. In corporations, this may reduce the number of themes you want to support. A large component may take it upon itself to support 2-3 supported and widely used design style guides. Then all you need to do is provide a single parameter (style guide name) to make the component use the right styles across the board.

What is going on inside?

Adding a component into your page is not only a matter of placement and visual style. Virtually all reusable components are interactive. A component can be self-contained (for example, all activity in a youtube player is confined to its bounding box), or expected to interact with the parent. If the component must interact with the parent, you need to consider the abstraction chain. Consider the simple countdown timer as a reusable component. Here is how the abstraction chain works:

timer-abstraction

The timer itself uses two low-level components – ‘Start’ and ‘Stop’ buttons. Inside the timer, the code will add click listeners for both buttons. The listeners will add semantic meaning to the buttons by doing things according to their role – starting and stopping the timer.

Finally, when this component is consumed by your page, only one listener is available – ‘onTimerCountdown()’. Users will interact with the timer, and when the timer counts down to 0, the listener you registered will be notified. You should be able to expect events at the right semantic level from all reusable components, from the simplest calendars to large complex components.

If a component can be made part of a larger document, two things you will care the most is serialization and dirty state. When users interact with the component and make a modification, you want to be told that the component is changed. This should trigger the dirty state of the parent. When the user clicks ‘Save’, you should be able to serialize the component and store this state in the larger document. Inversely, on bootstrap you should be able to pass the serialized state to the component to initialize itself.

Note that the actual technology used does not matter here – even the components embedded using iframes can use window.postMessage to send events up to the parent (and accept messages from the parent). While components living in your DOM will resize automatically, iframe-ed components will need to also send resizing events via window.postMessage to allow the parent to set the new size of the iframe.

The long tail

More complex reusable components don’t only have client-side presence. They have a need to call back to the server and fetch the data they need. You can configure such a component in two ways:

  1. You can fetch the data it requires for the component. In that case, the component is fully dependent on the container and it is container’s responsibility to perform all the XHR calls to fetch the data and pass it to the component. This approach may be best for pages that want full control of the network calls. As an added bonus, you can fit such a component into a data flow such as Flux, where some of the data may be coming from Web Socket driven server-side push, not just XHR request.
  2. You can proxy the requests that the component is performing. This approach is also acceptable because it allows the proxy to control which third-party servers are going to be whitelisted.
  3. You can configure CORS so that the component can make direct calls on its own. This needs to be done carefully to avoid the component siphoning data from the page to servers you don’t approve.

On all of these cases you may still want to be told about the events inside the web component using the component events as discussed above.

Frameworks are just the beginning

So there you go – all the problems you need to wrestle with when trying to reuse components in a larger project. Chances are the component is written in the ‘wrong’ framework, but trying to make the component load in your page is only the beginning. Fitting the component into the page visually, figuring out what is happening in it events-wise, and feeding it data from the server is the real battle. Unless you are trying to load a calendar widget, this is where you will spend most of your time.

© Dejan Glozic, 2016

Socket.io for Tardy React Status Indicators

The White Rabbit, Wikimedia Commons
The White Rabbit, Wikimedia Commons

In one of my favorite movies “The Blues Brothers”, the wife of the trucker pit stop owner proudly exclaims that they play ‘both kinds of music – Country and Western’. Readers of my blog know I too tend to serve two kinds of articles. In think-pieces, I tend to pontificate on a topic that buzzes between my ears that week. In ‘hey, look at this code we wrote’, I share something we learned by doing. I am sure there is an audience for both kinds but if you are in the latter camp, this is your day.

I’m late, I’m really really late

The problem we had to solve recently was as follows: a React store contains a list of items. These items are rendered in a hierarchy of React components, with a ‘dummy’ React component rendering a card for each item. The item has a number of visual elements on it that can be easily rendered from the item’s properties, but it also contains a status indicator.

server-cards

This status indicator was killing us: when we fetch the array of items via the XHR API call, we can get them fairly quickly. However, each item represents an entity that can be working or not working (and therefore have a green or red status indicator). Computing this status takes a while, needs to be done separately for each item, and cannot hold the main XHR call.

We solved this problem with the help of the Socket.io module (at this point I need to remind you we use Node.js for our server side). You can apply the solution even if you are not using it, nor using Node at all – just use whatever Web Sockets library comes with your stack of choice.

The devil is in the pudding

OK, on to the details. What we do is as follows:

  • Whenever we want to update the status of the store, we issue an XHR.
  • The XHR fetches the items on the server via a downstream API call.
  • Before sending the response, the server endpoint initiates an array of async parallel calls to obtain status for each of the items. It sends the response to the client without waiting.
  • The client renders the cards, with the status rendered as a gray circle.
  •  When the status API calls return, the result is sent back via Web Socket channel as an event.
  • On the client, this event is converted into a Flux action, which in turn updates the Store, which updates the views.

react-status-sequence

Produce the code

OK, enough architecture, produce the code. In the interest of space conservation, I am going to assume you have rudimentary knowledge of both React and Flux. If not, Google away until React components, dispatcher, actions and stores are all concepts that make sense to you.

Our action creator is capable of dispatching two actions – fetching items and initiation service status update:

var AppDispatcher = require("./dispatcher");

var ServiceConstants = require("./action-constants");

var ServiceActions = {
	fetchItems: function(data) {
		AppDispatcher.handleViewAction({
			actionType: ServiceConstants.FETCH_ITEMS,
			data: data
		});
	},
	serviceStatusUpdate: function(data) {
		AppDispatcher.handleViewAction({
			actionType: ServiceConstants.SERVICE_STATUS_UPDATE,
			data: data
		});
	}
};

module.exports = ServiceActions;

OK, on to the ItemStore. It is a fairly standard affair. When asked to fetch items, it makes an XHR request to the endpoint in the Node.js server that returns server items. When status update arrives, it merges the provided status with the items and fires a change event again. This will drive the view to re-render:

// Modules

var Constants = require("./action-constants");
var EventEmitter = require("events").EventEmitter;

// Globals

var AppDispatcher = require("./dispatcher");
var XhrUtils = require("./xhr-util");

var EVENT_CHANGE = "items";
var items;
var emitter = new EventEmitter();
var listeningForSocket = false;

// Public Methods ------------------------------------------------------------->

var ItemStore = {

	getItems: function(type) {
		return items;
	},

	emitChange: function(data) {
		emitter.emit(EVENT_CHANGE, data);
	},

	addChangeListener: function(callback) {
		emitter.on(EVENT_CHANGE, callback);
	},

	removeChangeListener: function(callback) {
		emitter.removeListener(EVENT_CHANGE, callback);
	}

};

module.exports = ItemStore;

// Private Methods ------------------------------------------------------------>

function fetchItems(url) {
	if (!url) {
		console.warn("Cannot fetch items - no URL provided");
		return;
	}

	// Fetch content
	XhrUtils.doXhr({url: url, json: true}, [200], function(err, result) {
		if (err) {
			console.warn("Error fetching assets from url: " + url);
			ItemStore.emitChange(Constants.STATE_ERROR);
			return;
		}

		items = result;
		ItemStore.emitChange(Constants.ITEMS);
	});
}

function serviceStatusUpdate(data) {
	for (var i in data) {
		var s = data[i];
		_updateStatus(s);
	}
	ItemStore.emitChange(Constants.ITEMS);
}

function _updateStatus(s) {
	for (var i in items) {
		var item = items[i];
		if (item.id===s.id) {
			item.status = s.status;
			break;
		}
	}
}

// Dispatcher ------------------------------------------------------------>

// Register dispatcher callback
AppDispatcher.register(function(payload) {
	var action = payload.action;

	// Define what to do for certain actions
	switch (action.actionType) {
		case Constants.SERVICE_STATUS_UPDATE:
			serviceStatusUpdate(action.data);
			break;
		case Constants.FETCH_ITEMS:
			fetchItems(action.data);
			break;
		default:
			return true;
	}

	return true;

});

Finally, the view. It fires the action that fetches items upon mounting, and proceeds to render the initial state with the loading indicator. Once the items are ready, it re-renders itself with the server items in place. Finally, when the status update arrives, it just re-renders and lets React diff the DOM for changed properties. Which is why we love React in the first place:

var React = require('react');
var Router = require('react-router');
var ItemStore = require('../flex/item-store');
var ActionCreator = require('../flex/action-creator');
var ActionConstants = require('../flex/action-constants');

module.exports = React.createClass({
  getInitialState: function() {
    return { loading: true, items: [] };
  },

  componentDidMount: function() {
    ItemStore.addChangeListener(this._handleAssetsChanged);
    ActionCreator.fetchItems("/api/items");
  },

  componentWillUnmount: function() {
    ItemStore.removeChangeListener(this._handleAssetsChanged);
  },

  _handleAssetsChanged: function(type) {
    if(type === ActionConstants.STATE_ERROR) {
      this.setState({
        error: "Error while loading servers"
      });
    } else {
      this.setState({
        loading: false,
        error: null,
        items: ItemStore.getItems() || []
      });
    }
  },

  render: function render() {
    var loading;
    var items;
    var error;

    if (this.state.loading) {
      loading = (
         <div className="items-loading">
            <div className="LoadingSpinner-dark"></div>
         </div>
      );
    }
    else {
      items = (
         <ul>
          {this.state.items.map(function(item) {
            var statusClass = "status-indicator";
            if (item.status==="active")
              statusClass+= " status-active";
            else if (item.status==="error")
              statusClass+= " status-error";
            else
              statusClass+= " status-loading";
            return (
               <li className="service-card" key={item.id}>
                  <div className="service-card-status">
                  <div className={statusClass}/></div>
                  <div className="service-card-name">{item.title}</div>
                  <div className="service-card-type">{item.dist}</div>
              </li>
            );
          })}
        </ul>
      );
    }
    if (this.state.error) {
      error = (
         <div className="error-box">{this.state.error}</div>
      );
    }
    return (
       <div id='list'>
          <h1>Servers</h1>
             This list shows currently available servers and their status (
             <span className="text-loading">gray</span> - loading,&nbsp; 
             <span className="text-active">green</span> - active,&nbsp; 
             <span className="text-error">red</span> - error)
          {loading}
          {items}
          {error}
      </div>
    );
  }
});

The status update portion involves Socket.io module. When the status is being computed, it is being emitted via the Web Socket. Of course, for this example we are faking the delay, but you can imagine actual status API request being involved:

var io = require('socket.io')(server);

function emitStatus(items) {
  var status = [];
  for (var i in items) {
    var item = items[i];
    var s = {};
    s.status = (Math.random()<.5)?"active":"error";
    s.id = item.id;
    setTimeout(function(status) {
      io.emit("status", [status]);
    }, (Math.floor((Math.random() * 900) + 100)), s);
  }
}

This status even is being picked up on the client, producing the status update action that is dispatched, picked up by the store and eventually causing the view to update:

  var socket = io.connect(location.origin);
  socket.on('status', function (data) {
  	ActionCreator.serviceStatusUpdate(data);
  });

Conclusion and commentary

One of the many realization we have come to using React in production is that one can get very far with views alone. A top-level view can make XHR requests, then pass the data down to child components as props. Child components can capture low-level events, and translate them into events of higher level of abstraction via callbacks passed in as props.

We realized many simple pages can be entirely done this way. What we have noticed though is that when Web Sockets and server-side events are involved, Flux architecture really comes to its own and shows its potential. Mixing server side events with events produced by users interacting with the UI is much better done using Flux.

The problem we tried to solve is rendering the initial page. If the user stays on the page for a prolonged period of time, status changes of the items can continue, but the code above can handle it without any changes. Of course, if others can create or remove server items, new events and actions are needed to model that.

As usual, the entire example is available as a Node.js app on Github, and I have deployed it in Bluemix so that you can see the app running here: https://react-status-demo.mybluemix.net. Just keep refreshing the browser to see the three-step rendering (page, then items, and finally status).

© Dejan Glozic, 2016

How to be a Good Software Architect

Wikimedia Commons
Wikimedia Commons

Ah, architecture – the broccoli of software industry. You know it is good for you, but you would much rather feed it to the dog under the table and move on to the ice cream. Ever since Joel Spolsky coined the phrase architecture astronauts, the role of architect has simultaneously been questioned by developers and line of business.

Developers suspect and occasionally despise software architects because they don’t like to be told what to do (they are wrong) and because architecture bestowed on them from the Ivory Tower is often confusing and verges on unimplementable (they are right).

Meanwhile, business suspects architecture because they don’t see how it solves its problems. Until you can ship iArchitecture 6s to the customers, business owners lack the direct link between architecture and bottom line. “I see what you are saying, Dejan, but in the last project a team of enthusiastic developers built a product on time without any architecture and it was just fine”. The fact that this product was an unmanageable steaming pile that nobody wants to maintain now didn’t help them draw the connection.

So what are we to do? Clearly, architecture is good for software the way vegetables are good for us. On the other hand, architecture created without any connection to the imperfect reality is useless. Selling architecture to executives is a fool’s errand. Is there a way out of this conundrum?

Of course there is, and is practiced as we speak in hundreds of companies. You just need to sneak the architecture in. Moms around the world know they cannot sell the broccoli to children by winning a rational argument involving the importance of nutrition. Instead, they either negotiate (first broccoli, then ice cream) or just sneak the veggies in. I don’t recommend you negotiate with business – like car salesmen, they are much more skilled in it than you are. Instead, just sneak the architecture in as part of normal development.

In order to be successful, you need to win over the two groups looking at you as if you are about to steal their lunch money.

The pragmatic architect

In order to win the developers over, you need to earn their trust. The easiest way to earn their trust is to become one of them. Architect of some kind is typically a role on the technical career path, on the way to Principal Engineer or Distinguished Engineer or Fellow. Notice the word “engineer” in the title. You have selected this path because you want to lead by example, to inspire, to make people follow you because they want to, not because of the org chart.

In order for developers to follow you enthusiastically, you need to get your hands dirty. Never stop coding! Coding is your anchor, your stabilizing force that prevents your architecture from morphing into unimplementable gibberish. The role of architecture is to give the code structure, a skeleton that prevents it from turning into an unmanageable goo. The role of practical architecture is to prevent the overgrowth of the said skeleton, before it turns a juggernaut into a WW I tank, with all of its speed and maneuverability.

It you are senior enough, it will be hard to code day in and day out. If you have the time for that, why are they paying you architect salary anyway? Spending too much time in the trenches may indicate that you are under pressure because people under pressure tend to slide back into a role they know best, and for you that is likely one of the coder. No, your role is more complex – you need to travel up and down the layers of abstraction constantly. You need to ascend to see the big picture that can be lost in the details, then descend to the details where the devil is, to make sure you kept all your pragmatic marbles.

What I like to do is go about two months ahead of the team. I anticipate the technical problems we are going to face, look for the possible solutions, write a prototype and blog about it (on this blog, in fact). By the time the team hits the problem in development, I have enough hands-on experience with it to speak about the problem without the imposter syndrome, a prototype, and a blog with code snippets (Blog as a Service). Works great, pays back tenfold.

Architecture in motion

On to the business. I already explained that architecture is not something you can directly sell to the business owners. People who love technology often derive pleasure just working with it. You learn a new language or a new framework and you are ecstatic. Executives look at you as you explain it and their eyes glaze over. But explain that the framework will cut operating costs in half due to the lower resource demands, or that it will cut time to market, and the room is yours.

Things are not very different in other walks of life. Actual architects may have a problem explaining the fact that load-bearing walls ensure building’s structural integrity. I bet they will have no problem explaining a pile of concrete, loss of revenue and a torrent of criminal negligence lawsuits. Architecture has to drive business impact, otherwise it is an intellectual exercise you should do on your own time (another Flux library, anyone?).

The problem with software is that it is hard to paint such a clear picture while it is being built. So don’t. Practice architecture in motion – infuse it into code while it is being built, don’t make it a separate phase. Blog about it, make diagrams for the teams so that everybody has a clear idea what you are building, write docs, define solid APIs, explain how everything fits together. Just don’t call it out as its own thing, because line of business does not care and cannot separate it from overall development cost.

Just say “we build good software”, and when the solidly architected product or service hums in production and does not implode from its own weight, say “because we are a great team”. Architecture is implied.

Lead it, own it

In order for all this to work, you cannot sit on the side occasionally bestowing architectural nuggets on the teams working on the project. Developers will politely listen to you but most of the leadership will come from the actual tech leads in the mud with the solders. Meanwhile, business will occasionally ask for your opinion but they will go to the tech leads for status. Don’t be the architect on the sidelines, be the technical leader using architecture as your secret weapon.

Then when you are in charge of the delivery, you can sneak the architecture in small doses into every feature, like parts of the wall Andy Dufresne sneaked into the yard in The Shawshank Redemption. The warden will never know.

© Dejan Glozic, 2016

Self-Contained Systems – Microservices for Dummies

Harran beehive houses, Wikimedia Commons
Harran beehive houses, Wikimedia Commons

I love the smell of the new year in the morning. As in the tweet above, there is something hopeful in starting a new blog by first updating the copyright notice at the bottom.

Nevertheless, what is currently occupying my mind is not as much how 2016 started, but how 2015 ended. As luck would have it, within weeks I had a chance to present about our production experience with micro services to two enterprises –  a mutual fund and a bank. Both were curious about them and simultanously unsure as to how they would apply in their unique situation.

In such discussions, the topic of Netflix inevitably comes up, and I am not sure this is a good thing. Sure, I enjoyed watching The Social Network like the most of us, but I am not sure it taught me much about how to become Mark Zuckerberg. Certain experiences, approaches and stories are so intensely singular that their utility as a ‘how to’ manual is quite poor.

In the case of Netflix, I have noticed two characteristics that are not very useful in most scenarios where micro services are considered:

  1. Very few outfits need to scale up to a third of all Internet traffic
  2. Being the micro service pioneers, Netflix engineers wrote a lot of custom code that is impractical in most situations

Maybe we don’t need 1000 microservices?

The consequence of the fact that you don’t need to prepare to handle a third of all Internet is that the overhead equation skews towards having fewer large micro services, rather than many small ones. In fact, it is surprising what transpires when discussions go a bit deeper into the ‘why’ direction.

As you probably know, I am on the record claiming that micro services are more about future-proofing, solving organizational problems of large teams and DevOps than any particular technology. It has become apparent to us as we talk to companies that the problem of two speed IT is more acute and pressing than replicating Netflix’s improbable feat. In the two-speed systems, companies can preserve investment and control through exposing the current system of record through APIs, while building up a cloud-based micro service system that consumes those APIs and serves Web and mobile experiences at the required speed and agility. You don’t need thousands of micro services for this.

In fact, more proof that the pragmatic pendulum has swung towards more reasonable architectures  can be found in the coining of a new phrase – Self Contained Systems (SCS). It is a neat workaround for the cognitive issues that may come from the term ‘micro service’. The term ‘system’ implies something larger, so even the illustrations of SCSs imply no more than a dozen or so. All the good properties of micro services are preserved (polyglot persistence, ability of teams to develop and deploy them independently, stack independence), but there is no expectation to deploy them in the hundreds and thousands. Sure, a self-contained system can in turn consist of several micro services, but at that point it becomes implementation detail.

It is probably best for companies dipping their toes into the micro service world to think about self-contained systems instead, lest they are taken down the Netflix path which will most likely be wrong for them.

I make my own underwear

The point of custom code from above reminded me of a story from the days when I was still climbing the audiophile ladder and cared about hi fi companies and stories about them. In this particular story from 2011, a parent company IAG that owns illustrious British names such as Quad, Mission and Wharfedale, describes its process like so:

One of the immediately notable things about IAG’s operation is the extent of what they make themselves: from new parts, to the tools to make those parts, through to all their own speaker drivers: the vast bulk of what goes into IAG products is made right there in the Shenzhen factory. They even manufacture their own wire.

What Hi Fi: Behind the scenes at IAG

The advice ‘start by making your own wire’ would make sense for very few companies, and the same applies to most enterprises trying to replicate Netflix’s approach. This comes into sharp focus when you start discussing concepts such as service discovery. Consider the following diagram:

service-discovery

The URL of the micro service system is composed based on spaces (dev, QA, prod) and regions. It can be easily constructed or scripted. The routing proxy partitions the path namespace, and each path acts as API and is driving a load balancer which in turn handles any number of micro service instances.

I am showing you this because we are running this successfully in production right now. If you want to, say, hit the development version of the micro service system running in US1 data centre, you would have something like https://foo-dev.us1.acme.com. A script with a couple of substituted variables is all you need to hit the system you want. As for the load balancer, it comes for free in the IBM’s Cloud Foundry-based PaaS (Bluemix).

If you have a Netflix-type system, you need service discovery just so that you can connect all your micro services, all flailing around at the unguessable IPs and port numbers. And since you need to build everything yourself, a simple thing such as load balancing that comes out of the box in all PaaSes and a number of IaaSes is something you need to provide.

Netflix story is unique for many reasons, and having to build everything yourself is one of those characteristics not necessary in 2016. Cloud today is all about what you can outsource to a PaaS or IaaS vs what is uniquely your value add. Building load balancers is doable but a rarely justified practice today.

For Dummies?

Yes, I know, forgive me for the click bait – SEO and all that. But by now you are well versed with the tongue-in-cheekness of the ‘For Dummies’ franchise. As people finding value in them are hardly dummies, so are people wisely choosing Self-Contained Systems instead of going down the path of the thousand micro services. Running a half a dozen to a dozen independently deployed, agile self-contained systems hooked up to your legacy systems may be the best choice for you right now. You can always add more, but don’t feel pressured to do so.

© Dejan Glozic, 2016

Dust.js as a React Delivery Vehicle

648px-Uniformed_Letter_Carrier_with_Child_in_Mailbag

Even people in love with Single Page Apps and pooh-poohing server side rendering know that SPAs cannot just materialize in the browser. Something has to deliver them there. Until recently, AngularJS was the most popular client side JS framework, and I have seen all kinds of ADVs (Angular Delivery Vehicles) – from Node.js (N is for Node.js in the MEAN stack), to wonderfully ironic JSP files serving Angular. Particularly exuberant developers go all the way to using static HTML to launch their apps into orbit, extolling the virtues of CDNs.

Of course, I would like to see their faces the first time they realize the need to compute something dynamically in those static files. But that is beside the point. The important takeaway is that AngularJS has a very nice property of being embeddable. You don’t need to surrender your entire page to Angular – you can sequester it to a DIV (in fact, you can have multiple Angular apps running in the same page). This is a very nice feature, but also a necessary one – again, AngularJS is a pure client side framework.

With great power…

React changes this equation because it can be rendered on the server. Similarly to AngularJS, React root component can be mounted to any node inside your page, but unlike Angular, this page can also be rendered on the server by React.

This opens the door for a whole new class of isomorphic or universal apps, and I have written about it already. What you need to decide is whether you want to render the entire page, or a subset of it. If you choose the latter, then the subsequent question becomes – how do you start the rendering process until React takes over?

My first inclination was to go full React. Using the awesome react-engine module, it is easy to configure React as the view engine in the Express framework, and render the entire page. However, we soon hit some snags:

  1. As we render our UIs using micro services that use UI composition to glue the pages together, we hit a problem of React being grumpy about having to render HTML snippet arriving from outside of its control – something much easier with a templating library such as Dust.js.
  2. JSX turned out to be fairly quirky and finicky when rendering HTML HEAD element, as well as trying to inline JavaScript in tags. In fact, the latter became so error prone that we completely gave up on it, electing to put all our script in files. I didn’t like this particular restriction, and this remains an area where I am sour on JSX and the fact it most decidedly isn’t HTML.

Of course the problems I listed above did not show up in the small example I published in the initial article. They reared their ugly head once we started getting serious. In my original example, the header was a React component. This works great if you control the entire app, but the whole deal of UI composition is to integrate with apps not necessarily written using React, and you can only do that using the least common denominator (HTML, CSS and vanilla JS).

Remind me again about UI composition

In a nutshell, UI composition is the approach where common areas on the page are served as HTML snippets from a REST API. The API service can also serve CSS and JavaScript files that accompany the snippet (if you don’t serve them from a CDN). The idea is that a dedicated microservice can be providing these common areas this way, allowing other microservices to pull the content and inline it in their pages regardless of their stack.

UI composition inverts the flow you would normally use with iframes. Instead of rendering the common areas, then placing an iframe for the content and loading the content from an external URL, we load the common area as HTML and inline it into our page. In the olden days this approach was often accomplished using ‘edge side includes’ or ESIs. This approach has many benefits, including no need for the dreaded iframes, full control over the entire page, and the ability to integrate microservices implemented using different stacks. For example, the teams in my current project use:

  1. Node.js microservices using React for isomorphic rendering
  2. Node.js microservices using Dust.js and jQuery
  3. Java microservices using AngularJS

All of these microservices render the exact same header even though they use different stacks and libraries. Powerful stuff.

OK, so React?

The problem here with React is that when we use it to render the entire page server-side, it starts to squirm in discomfort. Inlining HTML is a problem for React because, while it can be used on the server, it was designed to shine on the client. Inlining raw HTML presumably obtained as a user input into DOM is a major security exposure without sanitization, and React will tell you so in no uncertain terms. Here is the line that inlines the shared header taken straight out of our production code:

<div dangerouslySetInnerHTML={{__html: decodeURIComponent(this.props.header)}} />

This is React telling us very clearly: “I really, really, really don’t like what you are asking me to do”. And this is even before we bring in react-engine. React engine is a PayPal module that enables isomorphism when combined with Node.js/express and react-router. We can render on the server, then pack the properties as part of the HTML response, hydrate the React components on the client and continue where we left off.

Only we have a little problem: notice that in the snippet above we have inlined the header by passing it down to the React component as a prop. What this means is that this prop (‘header’) will be sent to the client alongside other properties. The only problem is that this property contains HTML snippet for the entire header, and because it can really mess up react-engine, it is also URLencoded, making it even bulkier.

This is an unhappy situation: first we inline the header HTML (which is fine), then we send that same inlined HTML, this time encoded, as a React prop to the client. This unnecessarily bloats the generated HTML.

RDV

This is what we are going to do to solve this problem: we are going to call back our trusty Dust.js sitting sad on the sidelines ever since we got smitten with React. We can press it into service to do what it does best – outline the page, prep it up to the point where React can take over.

It’s a good thing that Express framework will happily handle more than one view engine. Of course, only one of them can be registered as default, but this just means that we will need to spell out the extension of dust files (because React is the default). Big deal.


var path = require('path')
, express = require('express')
, renderer = require('react-engine')
, dust = require('dustjs-linkedin')
, helpers = require('dustjs-helpers')
, cons = require('consolidate');

...

// create the view engine with `react-engine`
var engine = renderer.server.create({
  routes: require(path.normalize(__dirname + '/public/routes.jsx')), 
  docType: ""
});

// set the engines
app.engine('.jsx', engine);
app.engine('.dust', cons.dust);

// set the view directory
app.set('views', __dirname + '/public/views');

// set jsx as the view engine
app.set('view engine', 'jsx');

// finally, set the custom view
app.set('view', renderer.expressView);

Once we have both engines set up, we can arrange our delivery vehicle like this. We will first set up a reusable layout template using Dust.js that will deliver the outline of each page:

<!DOCTYPE html>
<html>
 <head>
   <meta charset='utf-8'>
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1" >
   {+headContent/}
   <title>
     {title}
   </title>
   <link rel="stylesheet" href="/css/styles.css">
 </head>
 <body>
   {header|s}
   <div class="main-content">
     {+mainContent/}
   </div>
   {+javascript/}
 </body>
</html>

Notice how inlining of the header now happens in Dust.js, relieving React from doing it. We can now use this template to render our page like this:

{>"layout"/}
{<mainContent}
<div id="react-mount-node">{spa|s}</div>
{/mainContent}
{<javascript}
<script src="/bundle.js"></script>
{/javascript}

We have created a DIV in the template above where we are mounting React, and we will inline the React server-side content using the ‘spa’ variable.

Our Express controller that will handle both Dust.js and React can look something like this:

var request = require("request");

module.exports.get = function(req, res) {
  var settings = {
    title: 'SPA - Demo',
    name: 'React SPA',
    selection: 'header-spa'
  };

  var headerUrl = "http://"+req.headers.host+"/header?selection=header-spa";

  request.get(headerUrl, function (err, response, body) {
    if (err)
      console.log(err);
    else
      settings.header = body;
    res.render(req.url, { name: settings.name }, function(err, html) {
      if (err) {
        settings.spa = err.message;
        console.log(JSON.stringify(err.stack));
      }
      else
        settings.spa = html;
      res.render("spa.dust", settings); 
    });
  });
}

The code above is what I call ‘React Delivery Vehicle’. It has three steps:

  1. First we fetch the header from the URL that is providing us with the header HTML snippet. We capture it into a variable ‘header’. In production, we will heavily cache this step.
  2. Then we render the React root component as usual. This will employ react-engine and react-router to render all the views necessary for the provided request URL. However, we don’t send the rendering to the response. Instead, we capture it in the variable ‘spa’.
  3. Finally, we invoke Dust.js view engine to render the full page, passing in the ‘settings’ object. This object will contain both the header and the content rendered by React. Dust will simply inline both while rendering the page outline. The result will be sent directly to the Express response.

Commentary

The solution described above plays to the strengths of both Dust.js as a server side template engine and React as a component library. Dust.js is great at rendering HTML outline the way you would expect, with no need to worry about JSX quirks around HEAD meta tags, or JavaScript inlining. React takes over to render isomorphic components into the mount node. This means we don’t need to send any data that is not needed on the client. This fixes the HTML bloat problem I mentioned before.

As for the negatives, setting up two rendering engines on the server has a slight overhead, and switching mentally from Dust.js to JSX adds context switching tax. Luckily, you can set up reusable Dust.js templates and not really worry about them too much – most of the action will be in JSX anyway.

We like this approach and are currently switching to it across the board. If you have alternative ideas or comments, drop me a line. Meanwhile, the source code for the entire example is available on GitHub as usual, and the sample app employing this mechanism runs on Bluemix.

© Dejan Glozic, 2015

Pessimism as a Service

As far as I can remember, I was forgetful (ironic, I know). I could be driving for ten minutes, wandering why I don’t see the phone Bluetooth symbol on my car’s dash, and realizing I forgot my cellphone at home. Lately, when I reach the door, I ask myself: “OK, what have you forgotten”? Not “have you forgotten anything” but “what”, assuming that an affirmative answer is a forgone conclusion. Such a negative, “guilty until proven innocent” approach saved me many times, but taxed my soul. Am I really that predictable? Is cynicism the only way?

As our super cool, micro-service packed, React supercharged project is picking up steam, I am looking at everything we have done and counting the ways we have deployed ‘Pessimism as a Service’ to production. These examples may seem disconnected to you, but I assure you, there is a cold, calculated thread binding them. Hey, it’s a totally accepted artistic form – my own omnibus, as it were.

Micro services and human nature

I said it before, and I will say it again – micro services are more about people and process than about technology. In his strained attempt to disguise his distaste for micro services, Martin Fowler has still mustered a fainted praise in the way micro services tend to enforce code modularity.

The trouble is that, with a monolithic system, it’s usually pretty easy to sneak around the barrier. Doing this can be a useful tactical shortcut to getting features built quickly, but done widely they undermine the modular structure and trash the team’s productivity. Putting the modules into separate services makes the boundaries firmer, making it much harder to find these cancerous workarounds.

Martin Fowler on Strong Module Boundaries

It this will not inject you with a healthy dose of Weltschmerz, nothing will. What he is saying is that reaching directly into modules instead of using proper interfaces is a tech version of a cookie jar, and instead of counting on your maturity and discipline, micro services simply hide the cookie jar or put it on a top shelf, were you can’t reach it because you skipped the gym too many times.

Large systems are built by real-world organizations, and people are messy, petty, complicated, full of hidden agendas and desires. Engineers who try to look at micro services as a rational system fail to grasp the potent property that requires high emotional intelligence to understand. And it is nothing new – in fact I posit that the first micro service architecture has been practiced by the Nipmuk Indians, living near the lake in today’s Massachusets of the impossible name Chargoggagoggmanchauggagoggchaubunagungamaugg. Translated, it is really a module boundary protocol:

You fish on your side [of the lake], I fish on mine, nobody fishes in the middle.


– Full Indian name for the lake Manchaug, shortened by locals not familiar with micro-service architecture

So, yeah. Ideally, a monolithic system could be highly modular and clean if implemented by highly disciplined, rational people impervious to human foibles. When you manage to hire a teamful of such people, do let me know. In the mean time, the jaded micro service system we are using is humming in production.

AKKA is not a true micro service system

True story – I went to present in the first Toronto Reactive meetup because: (a) I mixed Reactive with React and (b) I wanted to learn what the whole Reactive Manifesto was by presenting on it. Hey, learning by doing!

As such, I was exposed to the AKKA framework. You can read all about Reactive in one of my previous blogs, but suffice to say that AKKA is a framework based on the ‘actor’ pattern and designed specifically to foster an asynchronous, dynamic and flexible architecture that can be deployed to a single server, and then spread out across any number of clusters as the needs grow.

There is a lot to like in AKKA, but I must sadly posit here that it is not a true representative of a micro service system. It is a system inspired by micro services, implementing many of their tenets and with some really nice properties. And yet it betrays one of the key aspects of micro services in that it is not pessimistic. In order to get the benefits of it, you need to lock yourself into a Scala/AKKA stack, paraphrasing the famous Ford Model T joke (you could order it in any color as long as it was black). You lose the ability to choose your stack per micro service.

This property is often misunderstood as a licence for anarchy – a recipe for disaster, cobbling together a concoction of languages, platforms, stacks and runtimes that nobody will be able to keep running and maintain. Of course that unchecked freedom has its price: a real world microservice system will most likely be using only 2-3 stacks (in our case, they ended up being Node.js and Java) and a small number of client side frameworks (for our extended team, React and AngularJS). But there is an ocean of separation between one and two platforms – the former representing lock-in, the latter being freedom.

As I always assume I forgot something, we should always assume that something better is just around the corner, and we don’t want to be hopelessly locked in when it arrives. But we also don’t want to bet our farm on it just yet. This is where the ability to start small is vital: we can try out new approaches in a single micro service without the obligation for a wholesale switch. AKKA requires that we profess our undying love to it and its Scala/JVM stack. Your milage may vary, but I cannot put all my money in that or any other single basket.

React is smart so you can be dumb

On to the client side of the the full stack. My readers know I have expressed my reservation about AngularJS before. I always found its syntax weird, its barrier of entry too high for a practical working system, and that’s before we even mention the version 2.0 schism. However, I always feared I will be viewed as ‘old man that yells at cloud‘ for not recognizing Angular’s genius, until React arrived.

You see, I got React instantly. I didn’t have to scratch my head and re-read its examples. When you read React code, you know exactly what is happening. Of course, that’s because it does less – just the View part. You need to implement Flux for coordinating actions, data stores and views, but Flux is even simpler, and consists of a single dispatcher module you fetch from NPM. You also need something like react-router in order to handle client side page switching. Then you need something like react-engine if you want isomorphic apps (I was told the new term is ‘universal’; I will use both for fun).

You may not fathom the difference in approaches between AngularJS and React until you watch the video explaining React’s design philosophy. You can tell that Facebook deploys React to production. In my opinion, Angular suffers from being designed by rock stars for other rock stars. Once you start getting real and deploying non-trivial apps to production, you need to scale, and that means increasing the number of people that can be productive with your framework of choice. React was designed with the assumption that if the framework is predictable and relatively simple, the velocity can be increased without the proportional increase in the bug rate. Otherwise, what’s the point?

React designers took human nature into account, assumed that we are all dumb at various times of day or week, and ensured that even in those unhappy moments, we can still read our React code and understand what it is doing with relative ease. It feels like a rotten compromise, but it is pure genius.

Web Components just around the corner

Ah, Web Components. The ultimate native component model that will solve Everything. Three years ago there was a lot of excitement, and people jumping on the polyfills to ‘temporarily’ shim the browsers until everybody implements them natively. Fast-forward to November 2015, and today you still cannot bet your project on them in production. Yes, they are natively implemented in Chrome, but if you didn’t want to use IE-only browser extensions 15 years ago, why would you do it when Google, and not Microsoft, is the vendor trying to sell its agenda as a standard.

Yes, there has been some movement on cross-browser support for Web Components, at least when Shadow DOM is concerned. Nevertheless, nothing stands still, and now some aspects of the ES6 module loading are at odds with HTML Imports (an important part of Web Components spec).

And of course, what has also happened in the last three years is that we got React. It has a very strong component model (albeit one that you can only peruse if you lock yourself into React), and more importantly, it extends to the server and even native rendering. This makes React attractive in ways that Web Components will never be able to match.

A year ago, we seriously toyed with the idea of just using shims until Web Components, clearly the future of the component models, arrive. I am glad I allowed my jaded self to prevail and instead used React – it helped us ship to production, with no performance compromises coming from shims, and looking back, we would be nowhere close to the promised glorious future if we allowed exuberance to sway our better judgement.

I am not saying ‘No’ to Web Components forever – they are actually not incompatible with React, and in fact a low-level Web Component can be used just like a native component in a React application, reaping the benefits of the DOM diffing. However, we don’t intend to write Web Components ourselves – we are fully isomorphic and server-side rendering gives us benefits that a comparable Web Component would not.

I predict that Web Components will be the way for incompatible frameworks to co-exist, the way to ‘fish in the middle’ of the Nipmuk lake mentioned above.

Optimism dreams, pessimism ships

These four examples show why enthusiasm and optimism rule the prototypes, meetups and articles, but pessimism takes over in production. Taking human nature into account, rolling with the imperfections of reality, expecting and preparing for the worst pays off tenfold once the projects get serious.

Now, if I can only remember if I turned the stove off before leaving home.

© Dejan Glozic, 2015

With React, I Don’t Need to Be a Ninja Rock Star Unicorn

San Diego Comic-Con 2011 - Lego Ninja, The Conmunity - Pop Culture Geek from Los Angeles, CA, USA

Followers of my blog may remember my microservice period. There was a time I could not shut up about them. Now, several blogs and not a peep. Am I over microservices? Not by a long stretch.

For us, microservices are gravity now. I remember an interview with Billy Corgan of The Smashing Pumpkins where, when pressed about his choice of guitar strings, he answered: “I use them”. That’s how I feel about microservices – now that we live and breathe them every day, they are not exciting, they are air. The only people who get exited about air are SCUBA divers, I suppose, particularly if they are running low.

ReactJS, on the other hand, is interesting to us because we are still figuring it out. For years we were trying to have our cake and eat it too – merge the benefits of server and client side rendering. I guess my answer to ‘vanilla or chocolate ice cream’ is ‘yes please’, and with React, I can have my chocolate sundae for breakfast, lunch and dinner.

The problem with ninja rock star unicorns

The magical creature from the title is of course the sought after 10x developer. He/she knows all the modern frameworks, sometimes reads about the not so modern ones just for laughs, and thrives where others are banging their heads against their desks repeatedly.

Rock star developers not only do not shy away from frameworks with high barrier of entry such as Angular, they often write there own, even more sophisticated and intricate. Nothing wrong with that, except that you cannot hire a full team of them, and even if you could, I doubt team dynamics would be particularly great. The reality of today’s developer job market is that you will likely staff a team with great, competent and potentially passionate developers. I say potentially because in many cases their passion will depend on you as a leader and your ability to instill it.

The React connection

This is where React comes into play. Careful readers of this blog may remember my aversion to JavaScript frameworks in general. For modestly interactive sites, you can go a long way with just Node.js, Express, a templating library such as Dust.js and a sprinkle of jQuery for a good measure. However, a highly dynamic app driven by REST APIs is too much of a challenge for jQuery or vanilla JS alone. I am not saying it cannot be done, but by the same token, while you can cut your grass with box cutters, it is massively less efficient than a lawn mower. At the end of the day, you need the right tools for the right job, and that means some kind of a JavaScript library or a framework.

What kept me away from Angular for the longest time was the opinionated nature of it, and the extent to which it seeks to define your entire world. Angular is a cult – you cannot be in it part time.

“Angular is a cult – you cannot be only a part time member.”

Not an Angular cult member

I have already written about why I got attracted to React from a technical point of view. There are great things you can do with isomorphic apps when you combine great React libraries. But these are all technical reasons. The main reason I am attracted to React is its philosophy.

We are all idiots at times

Angular used to pride itself as a ‘super-heroic JavaScript framework’. Last time I checked, they removed it from the home page (although it still appears in Google searches – ironic, I know). I presume they meant that the framework itself gives you super-hero powers, not that you need to be a super-hero developer in order to use it, but sometimes I felt that way.

I am singling out Angular somewhat unfairly – most MVC JavaScript framework approach the problem by giving you tools to carefully wire up elements on the page with events, react to watched variables, surgically change styles, properties, collections and so on. Sounds great in the beginning, until you scale to a real-world application, and things become really complex.

This complexity may not be a big deal while you are in the thick of it, coding like a beast. You may be a great developer. The problem is that the moment you turn your head away from that code, you start the ‘idiot’ clock – until that time when you no longer remember how everything fits together.

Now, if you are looking at your own code and cannot figure out how it works, what are the chances another team member will? I long ago proclaimed that dumb code is good and smart code is bad. Not bad code, just straightforward, easy to understand, ‘no software patent here’ code. Your future self will be grateful, future maintainers doubly so.

React allows us to write boring code

Let me summarize the key React philosophy in one sentence:

“Something changed in my application’s state. Better re-render it.”

React in a nutshell

I cannot emphasize enough the importance of this approach. It does not say “watch 50 variables and do surgically change DOM elements and properties when something happens in one component, then cascade those surgical changes to other components also watching those components”. Behind this, of course, is React’s ingenious approach of using a virtual DOM and only updating the real DOM with the actual changes between the two. You can read about it on React’s web page.

After many years of ‘surgical’ JavaScript DOM manipulations, there is something completely counter-intuitive about ‘just re-render’ approach. It feels like it should not work. It feels wasteful to keep creating all those JavaScript objects, until you realize that they are really cheap, and that the true cost are actual DOM manipulations.

In fact, you can use this approach with any JavaScript rendering engine – Mustache, Handlebars, Dust. The only problem is – if you try the ‘something changed, re-render the component’ approach there, templates will re-render into inner HTML, and that is wasteful. It is also potentially disruptive if users are interacting with form elements you just recycled under their feet. React, on the other hand, will not do it – it will carefully update the DOM elements and properties around the form controls.

Increase velocity without increasing bug rate

The key design goal of React was to help real world projects running code in production. Developers of modern cloud applications are under constant pressure from product management to increase velocity. The same product management of course expects you to maintain quality of your apps, which is very hard. It is not hard to imagine that shortening the cycles will increase the bug rate, unless the code we write is simplified. Writing ‘surgical’, intricate code in less time is asking for trouble, but React is easy to understand. There is uniformity in its approach, a repeatability that is reassuring and easy for people who didn’t write the code originally to understand when they pick it up.

Developers take great pride in their work, and sometimes they get carried away by thinking that code is their deliverable. They are wrong. What you are delivering are user experiences, and code is just means to an end. In the future, we will just explain what we want to some more powerful Siri or Cortana and our app will come to existence. Until then, we should use whatever allows us to deliver it with high velocity but without bugs that would normally come with it.

For my team, React is just the ticket. As is often in life, YMMV.

© Dejan Glozic, 2015