JavaScript: Web Servers of the Future

I posted an article about the History of Data Validation and I think that was only half of the full idea that was rattling around in my head.  Recently I've been doing a lot of work on single-page applications and the technologies that make them possible, but what's really interesting in this world is how to reuse server assets on the client and vice versa.  At the end of my previous post I was talking about Node.js and sharing server code with the client.  I believe that is how all web applications will be written in the future; the specific technology might vary, but conceptually that's how they will be built.

Don't believe me?

Microsoft has been developing TypeScript for several years now and many view it as a competitor to languages like CoffeeScript.  I don't think that is the case at all.  TypeScript's primary goal is to allow developers to write enterprise-scale JavaScript applications in a manageable, reliable, scalable, and structured way; they're trying to eliminate the fragility inherent with JavaScript.  TypeScript accomplishes this by making it easy to write modular code and by layering in a type system that gives you compile-time checking (which also gives you Intellisense).

On top of that, Microsoft has continued to advance the Windows Runtime for some time now, which allows you to write Windows applications in JavaScript.  That JavaScript code loaded in the Windows Runtime is then executed in a hosted instance of Chakra, the JavaScript engine powering Internet Explorer 11 (it started in IE9).  This is very similar to Google's V8 JavaScript engine that is used to power Node.js.  Not too long ago, Microsoft actually released an API for Chakra that allows you to host the JavaScript engine inside your own application, which means that someone could build a Node.js-like web server that runs on Chakra if they really wanted to.

I think JavaScript is quite powerful and the benefit of using the same technology on the server and the client has an incredible amount of potential that's on the cusp of being tapped.  As soon as you have a truly shared code base between the client and server, I think the traditional division of where functionality belongs will get fuzzy.  This means that you're free to shift more of your application to the server or push more of it into the client with very little effort; it's entirely up to you and the requirements of the application you're building.

Still need proof of the impending shift?  It's already happening in places you might not expect.

Since Microsoft has been putting such a huge investment into TypeScript, I can't help but think they saw this coming a long time ago.  In fact, Microsoft's project "Monaco" (a Visual Studio IDE in the browser) is 100% TypeScript on the client and on the server, and it runs entirely on Node.js (not IIS like you might have expected).  TypeScript has allowed them to build a massive JavaScript application with complete confidence in their code base.  I saw a really interesting talk at BUILD about this very topic.

If you're a server-side developer and don't know anything about JavaScript, I encourage you to learn it now while you're still ahead of the game.

SignalR: Tame Your AJAX

SignalR is a pretty interesting technology.  It's primary use-case is really about push notifications from your server to your clients.  This can be leveraged to do all sorts of cool things like message broadcasts and returning results to the client in a truly asynchronous manner.  What I propose however, is that SignalR can be used instead of traditional your traditional AJAX calls.

I've spent quite a bit of time trying to figure out the best way to deal with data transport to and from the browser in a manageable, traceable, and consistent way.  I looked at a variety of technologies to help out here:

WebAPI: This could also be standard MVC controllers, but essentially you have control over how your endpoints are structured, you can control serialization, and a variety of other things.  This is really the standard technology in the Microsoft world for standing up RESTful endpoints.  Again, this is just on the server, so you need to look elsewhere if you want help managing things on the client.

JSend: This is a standardized structure that you should wrap all of your AJAX responses in to give you a consistent way to handle results and error messages.

Vanilla JavaScript: You can make AJAX calls on your client to any server endpoint.  It's up to you to manage everything.

jQuery: This provides some syntactic sugar for your AJAX calls, but you're still on your own to manage the endpoints themselves.

Amplify: This is a library built on top of jQuery that allows you to define all of your endpoints in a centralized place.  This is a huge step forward since it minimizes the maintenance associated with URL management, query strings, and more.

Before I decided to try SignalR, I was using WebAPI and Amplify with JSend wrappers.  This was good, but there was still more manual upkeep that I'd prefer.

Now, take a moment and imagine a world where:

  • you can define RESTful (or at least RESTful-esque) endpoints on your server
  • your client magically knows about all of your server endpoints
  • your client-server programming model is more like remote procedure calls
  • your JavaScript files have complete IntelliSense for your server endpoints
  • you never have to maintain any URLs for your server calls
  • you never have to deal with (de)serialization on the client or the server
  • your server can push notifications to your client
  • your client can make synchronous or asynchronous calls to your server
  • your client and server will automatically figure out the best way to talk to each other

Sound good?  That's what SignalR can do for you; if you only think about SignalR as a persistent connection, then you're missing out on a ton of the benefits.

What's all of this look like?  If you're just using it as a replacement for WebAPI, it's actually pretty close; you could easily grab your WebAPI code and tweak it into a SignalR Hub.  On the client is where you really see a difference.  I'll leave you with a code snippet:

var person;

//SignalR (with full IntelliSense)
person = connection.personHub.server.getPerson(1);

//jQuery
$.ajax({
  url: '/api/person',
  type: 'GET',
  success: function (data, textStatus, jqXHR) {
    person = data;
  },
  error: function (data, textStatus, errorThrown) {
    //Handle error
  },
  contentType: "application/json",
  data: JSON.stringify({ personId: 1 })
});

On a final note, please keep in mind that I'm using this to build a large business application that requires users to log in before they can do anything.  I certainly wouldn't recommend SignalR for a public site with millions of concurrent visitors, but for a business application that only deals with thousands of users, it's a technology choice that can give your developers a significant productivity boost.

JavaScript MV*: Knockout & Durandal

I've been doing a lot of work with JavaScript MV* frameworks lately and I thought it would be a good idea to write down some of my experiences.  This isn't going to be about which framework is better, this is just my opinion about several frameworks based on my experiences with them.  I've got quite a bit of experience using Knockout on several projects, so I thought that would be a good place to start.

Knockout

This isn't an MV* framework in the fullest sense.  It's a really good data binding library, that also happens to render small HTML templates (really just snippets).  There are a lot of comparisons made between Knockout and MV* frameworks, but I think anyone that tries to make those comparisons either doesn't understand what Knockout is trying to accomplish or doesn't understand what the other frameworks were designed for.  I don't blame them though.  It took me quite some time to get my head around the complex landscape that is client-side MV* frameworks; for the longest time I thought Knockout versus Angular was a valid comparison, but now I know it's not.

In my opinion, Knockout has two use-cases that it's really good at:

  1. Adding a layer of rich client-side interactivity to a server-side MV* framework.
  2. Serving as the data binding component in a client-side MV* framework you assemble yourself.

In either case, Knockout is only one component of an MV* framework; it isn't a complete MV* framework on its own.  In the first scenario, I've successfully used it in the past to add rich client-side interactivity to a traditional ASP.NET application.  In the second scenario, you could build your own MV* framework using various specialized libraries (e.g. data binding, routing, etc.) or you could use a framework that someone else has assembled using the same methodology.  In this particular instance I'm referring to Durandal (which I'll talk about shortly).

If you decide to use Knockout for either scenario I would recommend a few things to get you started in the right direction:

  1. Don't mix your JavaScript and your HTML; keep them completely separate.  I've covered this specific topic before and the quick summary is to use the classBindingProvider plugin to keep your HTML and your logic separate.
  2. Spend some time thinking about how you should structure your JavaScript models and logic.  Knockout doesn't care how you structure your code, but if you don't come up with a standard structure it will quickly get out of hand (especially if several developers are working on it at the same time).
  3. If the models coming from your server are big and complicated, the default mapping plugin might not cut it.  I've had good experience with the viewModel mapping plugin and I'd recommend it to others if you have to deal with these more complex scenarios.
  4. If you're only targeting browsers that are ECMAScript 5 compliant (IE9+), then I'd recommend using the Knockout ES5 plugin.  This plugin makes use of ECMAScript 5 getter/setter pairs, which means that you don't have to remember all of the parentheses the Knockout traditionally demands.

Durandal

This is the framework that should be used when attempting to compare Knockout with various MV* frameworks.  Durandal is a fully-featured MV* framework that uses Knockout as its data binding mechanism, along with few other libraries and some custom code to make everything work well together.  If you're a big fan of Knockout or have a lot of experience with it, using this framework is an easy way to take your first step into the client-side MV* world.

I don't have a ton of experience with this framework compared to a lot of the others, but I did spend a full week building various demos to give this framework a fair chance.  Based on my limited experience, Durandal does one thing very well:

  1. It makes it very easy to create a client-side MV* application if you have experience with Knockout and the standard ASP.NET stack.

It's great for that and I found it very easy to use given that background; however, I believe Durandal has some weaknesses:

  1. It has a very small community compared to the other major players in this space.  This is fine for small applications, but when you need to build bigger applications that you need to support for years, a large community becomes a significant resource that must be considered.
  2. By definition, the framework is an assembly of several other libraries.  For some this could be an asset since you can easily switch-out components.  For me, if I'm reaching for a large framework like this to start with, I'd actually prefer something that was designed end-to-end with that intent.
  3. The project is maintained largely by a single developer.  Rob Eisenberg has done great work and I'm honestly impressed with everything he's done, but having a larger number of people backing the project and driving it forward gives me more confidence that it will be around for a long time (I know that's largely an illusion, but it still makes me feel better).
  4. There was recently a failed Kickstarter to fund the next phase of development.  I know that doesn't signal the death of the project, but it doesn't inspire confidence that this is something that the community will get behind for years to come.

Again, I think it's a great framework for what it's good at, but it just didn't match the criteria for the project I was evaluating it for.

JavaScript MV*: Library vs Framework

The landscape of JavaScript MV* frameworks is complicated for anyone just tuning in; when I first tried to get caught up on everything, it was certainly confusing and I had no idea where to start.  Once I had it all figured out, I then had the challenge of explaining it to everyone around me, which I couldn't articulate well until I saw this video of Tom Dale and Yehuda Katz.  After I saw that, everything I was trying to explain finally clicked and it was just a matter of plotting all of the frameworks on a graph:

library_vs_framework.png

The graph is less about each framework's exact position and more about illustrating an idea.  That idea is simple:

In order to build any large application you need to use a rigid, opinionated framework.

Now, I'm certainly not saying that if you want to build a large application you have to use something like Ember or Chaplin.  What I'm saying is that you have the choice between using a framework that already exists or you'll have to write your own by using one of the low-level libraries and then build up your own opinions on top of that.  However you slice it, you effectively end up at the same place before you're able to build a large-scale application.

I've read countless articles about developers using Backbone (or similar low-level library) and most of them sound like this:

"Backbone was rough at the start, but now it's the best!  It took us about a year to figure out all of the patterns and structure we wanted, but now that all of the developers are on the same page it's going pretty well."

I'm sorry, but did you say a year?  I'm not joking; I actually read an article where it took the team a full year before they didn't hate working with it.  What took so long?  That was how long it took them to figure out how to structure their code, and define their internal patterns and best practices in a way that made sense for all of the developers on the team.

Wow.

Sure that's Backbone though, and everyone knows that Backbone is only a library.  Well, I know lots of people love Angular and believe it's the best thing out there, but I really think it is midway between a library and a framework.  It gives you more tools and higher-level abstractions than something like Backbone or Knockout, but it completely abandons you on when it comes to application structure and best practices.  After watching one of the teams at Google talk about their experiences building a large Angular application, it just reinforced my view; a lot of what they talk about is their struggle to find a structured way to build the application.  That's right, Google is struggling to find structure with their own tool.

I'm not saying that any specific library or framework is good or bad.  All I'm saying is that you should pick the right tool for the right job.  You shouldn't waste your time figuring out best practices and code structure if there's already something out there that's close enough.  Of course, if you're only building a small application or there's only one developer, the benefit of the larger frameworks isn't as clear and it's more likely to just get in your way.  In the end, you should be spending your time solving problems unique to the application you're building and not fiddling around with the tooling underneath it.

Apply Business Logic Like CSS

Providing a rich client experience in the browser has been something that we (as a community) have been trying to do for as long as I can remember.  You don't have to look very hard to see the evolution of our attempts.  Over the course of a decade or so there have been several efforts to make this a reality: ActiveX controls, Java applets, Flash, and Silverlight are just the ones that I can name off the top of my head.  As support for ECMAScript 5 grows (and with the death of Internet Explorer 8 just around the corner), we're finally in an era where we can provide a rich client experience in the browser with nothing more than JavaScript.

This is certainly an exciting time, but just because the technology is available, that doesn't mean developer adoption is guaranteed to be high.  Why is this?  Surprisingly, most of the developers that I'm aware of are happy relying on the server-side technology they're so comfortable with; the shift to a thick-client in the browser means that a lot of developers will need to be pushed out of their comfort-zone.  I think this is an incredibly promising area, but many developers will need to be introduced to the concepts slowly in order to get buy in.

Admittedly, when I first tried to push more interactivity to the client I was a little lost.  In my latest project I decided that we'd try to layer in more client-side interactivity than we've done in the past, but I wanted to do it in a maintainable way.  I didn't want it to be bolted on at the end of the project with jQuery plugins; I wanted the interactivity to have first-class support in our application.  I also didn't want beautifully structured server-side code that does a hand-off to client-side code that's spaghetti.  After all, a rich client isn't worth it if it's a nightmare to maintain.

Over the last few years I've had my eye on Knockout and the ecosystem surrounding it.  Based on everything that I knew about it, it would be a good addition to Microsoft's standard MVC stack.  The problem with vanilla Knockout is that there isn't a good separation of concerns when it comes to your views and the logic to display them.  For instance, a standard Knockout view would have snippets JavaScript code throughout it like this:

<div data-bind="visible: myFunction() > myValue">
  Some Text
</div>

Obviously that's a simple example, but as you build more complex logic these inline JavaScript snippets can get out of hand.  Luckily there is a handy plugin that allows you to pull this logic out and apply it to your view like CSS tags:

<script>
  var bindings = {
    myClass: function(context, classes) {
      return {
        visible: this.myFunction() > this.myValue
      }
    }
  };
</script>

<div data-class="myClass">
  Some Text
</div>

I've left out the standard Knockout code to bind everything together, but hopefully you can see that this will allow you to completely separate your view from the logic behind it.  Just getting that separation is a huge benefit, but you can do something much more powerful with this basic construct.  With CSS you define small reusable classes and then combine them on your view to build a more complex style.  Just like CSS, you can begin to apply functional behavior the same way:

<script>
  var bindings = {
    show: function(context, classes) {
      return {
        visible: this.isMessageVisible()
      }
    },
    message: function(context, classes) {
      return {
        text: this.getMessage()
      }
    }
  };
</script>

<div data-class="show message">
  Message will be shown here.
</div>

This simple concept allows you to build tiny reusable pieces that define behavior.  You can then apply multiple behaviors to individual elements (or a hierarchy of elements) to compose more sophisticated behaviors.  In my latest web application I've built behavioral classes for tons of basic things: show, hide, valid, invalid, enable, disable, and other more complex classes that represent common behaviors in my business logic.

This method could certainly use some improvements, which I hope to work on in the future, but this is still miles ahead of where we were a few years ago.