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

Advertisements

Should I Build a Site or an App? Yes!

Minnesota State Capitol Woodworkers Toolbox, circa 1900, Wikimedia Commons.
Minnesota State Capitol Woodworkers Toolbox, circa 1900, Wikimedia Commons.

Yes, I know. I stopped blogging to take a desperately needed break. Then I returned only to be hit with a mountain of fresh, ‘hit the ground running’, honest to God January work that knocked the air out of my lungs and pinned me down for a while. Then an IBM colleague tried to ask me a Dust.js question, my doors were closed due to a meeting, and he found his answer in one of my blog posts.

So my blog is actually semi-useful, but it will stop being so without new content, so here is the first 2015 instalment. It is about one of my favorite hobbies – being annoyed with people being Wrong on the Internet. Judging by various discussion threads, developers are mostly preoccupied by these topics:

  1. All the reasons why AngularJS is awesome/sucks and will be the next jQuery/die in agony when 2.0 ships (if it ever ships/it will be awesome/cannot wait).
  2. Picking the right client side MVC framework (lots of people out there frozen into inaction while looking at the subtle differences of TODO app implementations in 16 different incarnations)
  3. Declaring client side single-page apps ‘the cool way’ and server side rendering ‘the old way’ of Web development

These topics are all connected, because if you subscribe to the point of view in (3), you either pray at the church of AngularJS (1) or you didn’t drink the Kool-Aid and subsequently need to pick an alternative framework (2).

Dear fellow full-stack developers and architects, that’s pure nonsense. I didn’t put an image of a toolbox at the top because @rands thinks it will nicely fit Restoration Hardware catalog. It is a metaphor of all the things we learn along the way and stash in our proverbial tool box.

Sites and apps

The boring and misleading discussion ‘server or client side apps’ has its origin in the evolution of the Web development. The Web started as a collection of linked documents with strong emphasis on indexing, search and content. Meanwhile, desktop applications were all about programming – actions, events, widgets, panes. Managing content in desktop apps was not as easy as on the Web. As a flip side, having application-like behaviour on the Web was hard to achieve at first.

When Ajax burst onto the scene, this seemed possible at last, but many Ajax apps were horrible – they broke the Back button, didn’t respect the Web, were slow to load due to tons of JavaScript (the dreaded blank page), and the less I say about hashes and hash bangs in URLs, the better.

It is 2015 now and the situation is much better (and at least one IBM Fellow concurs). Modern Ajax apps are created with more predictable structure thanks to the client side MV* frameworks such as BackboneJS, AngularJS, EmberJS etc. HTML5 pushState allows us to go back to deep linking. That still does not mean that you should use a hammer to drill a hole in the wall. Right tool for the right job.

And please don’t look at native mobile apps in envy (they talk to the server using JSON APIs only, I should do that too). They are physically installed on the devices, while your imposter SPA needs to be sent over mobile networks before anything can be seen on the screen (every bit of your overbuilt, 1MB+ worth of JavaScript fatness). Yes, I know about caching. No, your 1MB+ worth of JavaScript still needs to be parsed every time with the underpowered JavaScript engine of the mobile browser.

But I digress.

So, when do you take out site tools instead of Web app tools? There are a few easy questions to ask:

  1. Can people reach pages of your app without authenticating?
  2. Do you care about search engine optimization of those pages? (I am curious to find people who answer ‘No’ to this question)
  3. Are your pages mostly linked content with a little bit of interactivity?

If this describes your project, you would be better off writing a server-side Web app (say, using NodeJS, express and a rendering engine like Handlebars or Dust.js), with a bit of jQuery and Bootstrap with a custom theme to round things up.

Conversely, these may be the questions to ask if you think you need a single-page app:

  1. Do people need to log in in order to use my site?
  2. Do I need a lot of complex interactive behaviour with smooth transition similar to native apps?
  3. Do I expect users to spend a lot of time in my app doing something creative and/or collaborative?

What if I need both?

Most people actually need both. Your site must have a landing page, some marketing content, documentation, support – all mostly content based, open to search engine crawlers and must be quick to download (i.e. no large JS libraries please).

Then there is the walled up section where you need to log in, and then interact with stuff you created. This part is an app.

The thing is, people tend to think they need to pick an approach first, then do everything using that single approach. When site people discuss with app people on the Internet, they sound to me like Abbott and Costello’s ‘Who’s on First?’ routine. Site people want the home page to be fast, and don’t want to wait for AngularJS to download. They also don’t want content people to learn Angular to produce new pages. App people shudder at the thought of implementing all the complex interactions by constantly redrawing the entire page (sooner or later Web 1.0 is mentioned).

The thing is, they are both right and wrong at the same time. It may appear they want to have their cake and eat it too, but that is fairly easy to do. All you need to do is apply some care in how your site is structured, and give up on the ideological prejudice. Once you view server and client side techniques as mere tools in the toolbox, all kinds of opportunities open up.

Mixing and matching

The key in mixing sites and apps is your navigational structure. Where SPA people typically lose it is when they assume EVERYTHING in their app must be written in their framework of choice. This is not necessary, and most frameworks are embeddable. If you construct your site navigation using normal deep links, you can construct your navigational areas (for example, your site header) on the server and just use these links as per usual. Your ‘glue’ navigational areas should not be locked in the client side MV* component model because they will not work on the server for the content pages.

What this means is that you should not write your header as an Angular directive or a jQuery plug-in. Send it as plain HTML from the server, with some vanilla JavaScript for dynamic effects. Keep your options wide open.

For this to work well, the single page apps that are folded into this structure need to enable HTML5 mode in their routers so that you can transparently mix and match server and client side content.

Now add micro-services and stir for 10 minutes

To make things even more fun, these links can be proxied to different apps altogether if your site is constructed using micro-services. In fact, you can create a complex site that mixes server-side content with several SPAs (handled by separate micro-services). This is the ultimate in flexibility, and if you are careful, you can still maintain a single site experience for the user.

To illustrate the point, take a look at the demo I have created for the Full Stack Toronto conference last year. It is still running on Bluemix, and the source code is on GitHub. If you look at the header, it has several sections listed. They are powered by multiple micro-services (Node apps with Nginx proxy in front). It uses the UI composition technique described in one of the previous posts. The site looks like this when you click on ‘AngularJS’ link:

fsto-angular

The thing is, this page is really a single-page app folded in, and a NodeJS micro-service sends AngularJS content to the browser, where it takes over. In the page, there are two Angular ‘pages’ that are selectable with two tabs. Clicking on the tabs activates Angular router with HTML5 mode enabled. As a result, these ‘pages’ have normal URLs (‘/angular-seed/view1’ and ‘/angular-seed/view2’).

Of course, when clicking on the links in the browser, Angular router will handle them transparently, but if you bookmark the deep URL and paste in the browser address bar, the browser will now hit the server first. The NodeJS service is designed to handle all links under /angular-seed/* and will simply serve the app, allowing Angular router to take over when loaded.

The really nice thing is that Angular SPA links can sit next to links such as ‘About’ that are a plain server-side page rendered using express and Dust.js. Why wrestle with Angular when a straightforward HTML page will do?

Floor wax and dessert topping

There you go – move along, nothing to see here. There is no point in wasting time on Reddit food fights. A modern Web project needs elements of server and client side approaches because most projects have heterogeneous needs. Once you accept that, real fun begins when you realize you can share between the server and the client using a technique called ‘isomorphic apps’. We will explore these techniques in one of the future posts.

© Dejan Glozic, 2015