Chapter 1. Introducing Ember.js and Ambitious Web Applications

These days, we web developers have it relatively easy. No, we’re not just celebrating the consensus that Internet Explorer 6 need no longer be fully supported—OK, yes, we’re also doing that. You see, in our day, we had to reinvent the wheel a lot. At the start of any given project, you would go scouring through previous projects for bits and pieces of JavaScript you’d written or borrowed that did things like iron out API differences between browsers, set up utility functions you’d grown accustomed to, and even generate HTML bits in reusable ways.

It happened so much that it felt less like reinventing the wheel and more like running inside a hamster wheel. We have a feeling that’s why Ember (hereafter referred to that way, without the “.js”) uses that cute little hamster as its mascot. Ember jumps into the wheel for you, freeing you to concentrate on what’s new and interesting about your particular project. We have it easy these days because we have our pick of dozens of well-designed toolchains, libraries, frameworks, and the like that offer such conveniences, but this book is about why Ember is particularly well suited to help you build ambitious web applications.

Ember won’t be useful to you, let alone make any sense to you, without understanding some of the underlying technologies and concepts it builds upon, as well as the problems it hopes to solve, so let’s dissect some of those first.

What Is an “Ambitious Web Application”?

Ember came to be as a successor—perhaps more a “spiritual cousin”—to the web-application framework SproutCore, a framework you’ve quite likely encountered on the Web, knowingly or otherwise.   If you’ve used any of Apple’s iCloud (formerly MobileMe) applications to check your email, locate and even remotely disable your phone with “Find My Phone,” or, most recently, create Pages, Numbers, or Keynote documents on the Web, you’ve used SproutCore. These are great examples of ambitious web applications: ones that look and act like desktop applications, but happen to be delivered via web technologies.

Such applications differ from much of web development in several important ways.

Ambitious Web Applications Are Not Documents

We tend to think that any sentence that starts with, “When Tim Berners-Lee” can be safely ignored, unless written by Sir Berners-Lee, but this time you’ll just have to trust us. When Sir Tim Berners-Lee created the World Wide Web, he was pretty clear about the use case he was building for. The backbone of his invention was the Hypertext Transport Protocol (HTTP). He was creating a better way to share documents. In his own words, he was “thinking about all the documentation systems out there as being possibly part of a larger imaginary documentation system.” This powerful technology allowed a browser to turn a URL, provided by the user, into a unique address to a server, which could be located anywhere in the world, and even to a specific document on that server, which could then be retrieved and rendered for the user. Browsing a site like Wikipedia is a canonical example of this model. When you click a link on a Wikipedia page or search for an entry on the site, the browser sends a request to load a new document—from a new URL. The entire page is replaced with the new content, and the URL shown to the user in the address bar changes. Although this is still a remarkable feat, it bears little resemblance to the expectations of a modern “web application.” In the years since the birth of the Web, we’ve come to expect a lot from desktop applications, from real-time data manipulations to eye-catching renderings and animations. In recent years, we’ve come to expect “web applications” to be no different.

Ambitious Web Applications Are Stateful

By design, the building blocks of the Web are stateless. “State,” for our purposes anyway, refers to data that changes and must be persisted in your application. For instance, if your user has checked a checkbox in your web form, you don’t want to uncheck that checkbox accidentally, just because you’ve forgotten. You want to remember that the state in which you found the checkbox last was “checked,” and that it should stay that way until a legitimate reason for it to change—the user clicks it again, or some logical scenario requires it be toggled or unchecked—comes along. Since HTTP is a stateless protocol, there’s nothing being passed back and forth between your browser and the server that describe this sort of state data. If you’re simply navigating from document to document, no state is necessary. If you’re building an application, however, you need to know things such as:

  • Is this user logged in?

  • Has this order been placed?

  • Has this message been sent?

Over the years, web developers have figured out a number of hacks for persisting state across sessions, using protocols that weren’t designed to enable such a thing. We’ve used URL-encoded state variables, cookies, and the like to keep track of what the user has done and is doing across multiple HTTP requests.

Those of us old enough to have used the Web in those days remember the pain of typing in a long expense report, email, blog post, or some more important document, only to have it disappear into the ether(net) when one of these state-persistence hacks failed. Until we filled this gap in the Web’s feature set, it would remain a document-delivery platform. When we’d truly solved this problem, the Web became an application platform. The solution to this problem was the XMLHTTPRequest, or XHR, a nigh-magical new capability that allowed your application logic to request data from or send data to the server without itself being unloaded and reloaded.

Microsoft gets a lot of flak from the web-development community, mostly for the sins visited on the world in the form of Internet Explorer versions previous to 8. To be sure, there were some serious oversights in those software releases. However, Microsoft is responsible, at least in part, for several of the Web’s biggest advancements. Internet Explorer 5.0 for the Macintosh was the first browser to fully support CSS, for instance. It was also Microsoft that invented the XHR.

The XHR abstracts the very soul of the browser; it allows JavaScript to make an HTTP request, just as the browser did historically, and deal directly with the response. This puts JavaScript—thereby, the JavaScript developer, not the browser itself—in control of the user experience. The user can enter a URL, such as http://mail.google.com, into the browser’s address bar, and the browser will load the Gmail application. From then on, the Gmail application’s JavaScript code is able to make additional HTTP requests to acquire more data—individual email documents, attachments, updated copies of the user’s address book, and gobs more—without reloading the page. If you don’t need to reload the page, it’s not necessary to jump through as many hoops to preserve state. Much has been written about how this made the Web more responsive, how it made web applications look and act more like desktop software. Gmail and Google Maps dazzled us with their desktop-grade experience and performance. Crucially, though, the XHR had the subtle effect of gaining our trust in the Web as a platform for application delivery.

With XHR, when a user hits “send” in an email application, for instance, the application can fire off a request to deliver the email data to the server. If this XHR fails, the page and all its data—including the email the user has written—remain on the page and in memory. The application can simply try again to deliver the data. This, in our opinion, fundamentally changed the Web. In combination with its newfound performance, this reliability made the Web a “real” application platform.

The trouble, then, became managing all the state that was not being flushed with regular page reloads.

Ambitious Web Applications Are Long-Lived

Modern web applications are now long-lived, meaning the application could be open in a browser instance for hours at a time without reloading the page. The upside, as we’ve celebrated, is that you can load gobs of additional data from the server without having to reload your application every time. The downside is that you now have to manage those gobs of data. If you simply keep adding data without releasing any of it, you will fill up your RAM in short order, locking up the browser and showing your user a “busy” cursor.

Ember, through features and through conventions, helps you take advantage of long-lived application development while avoiding memory leaks. Ember’s view management automatically cleans up unused variables and bindings for you as views are shown and hidden. Ember’s conventions for navigating from one view to another also encourage you to pass objects from one to another, saving you the trip to the server to reload data for a particular view, if it has already been loaded, and saving you from inadvertently having two or more copies of the same object in memory.

And potential memory leaks aren’t the only challenge. The kind of application that sticks around for several hours won’t likely all fit within a jQuery ready callback. Without some smart structure to your codebase, adding and maintaining features that could be used at any time and repeatedly can become quite difficult.

Ambitious Web Applications Have Architecture

Now that we have these long-lived pages persisting all of this state data, we’re going to need some organization and planning. If the code that enables the user to write an email is living on the same page as the code to allow the user to delete an email, we have to ensure that the right bit of code is executing so we don’t delete an email we intend to send. We want to make sure the right data is being accessed—we don’t want the code that sends the body of an email to accidentally send the user’s address book instead. And if we create a great scrolling list feature for our inbox, we don’t want to have to do all that work again for our sent items, junk mail, and favorites lists.

In the late 1970s, architects began thinking about common design challenges and their solutions as reusable patterns. Rather than starting every project with a blank slate and independently arriving at the conclusion that this doctor’s office was going to need a large room with lots of seating where patients could wait until the doctor was ready to see them, they identified design patterns, such as the “waiting room,” an abstract concept that could be implemented whenever useful. You could then have a name for the phenomenon and ask questions such as, “Do we really need a waiting room for this build?” You could also better define the concept itself: “You can’t have a waiting room without places to sit.”

Model-view-"whatever-you-want-to-call-it”

A few years later, information architects realized the same approach could be useful in software architecture. We software architects were already employing a similar, if more abstract approach with . For software architecture, design patterns could give us a middle ground—between object and implementation—to talk about common feature sets and requirements. One of the more popular patterns to come out of this movement was the , which describes:

  • A model, in the sense of a mathematical model, that describes a set of domain-specific data. An application can, and likely does, include multiple models. A user model, for instance, would include attributes describing users, such as their names, dates of birth, permissions, and so on.

  • A view, which is the face of the application, the representation of the model data and features the application offers for interacting with that data. Most often in software this is a graphical user interface (GUI) with text, images, and widgets, such as buttons, dropdowns, and form fields.

  • A controller, which is the home of the application logic and can access the model, populates the view with data retrieved from the model and responds to interaction events instigated by the user and relayed by the view, in turn manipulating the data in the model and controlling which of potentially multiple views is in use.

This pattern has seen extraordinary success in desktop software and server-side architectures in the last 30 years, but it’s a relatively new concept for web developers. A few years ago, a server-side engineer friend of ours asked, “Why are client-side developers talking about MVC so much all of a sudden? What do they care? They are the view!”

There are myriad flavors and interpretations of MVC, many of which take issue with the term “controller.” For that reason, you may see it abbreviated MV* so as to include patterns that replace the “controller” with “routers,” “view controllers,” and other concepts.

Separating your code into packages dedicated to models, views, and controllers is not magic. It’s simply a way to ensure that you’re separating concerns, encapsulating functionality and data into discrete objects with a singular, modular purpose, the way a good object-oriented programmer should. It’s also a conventional organization. If you know that someone employed the MVC pattern in a project, you know where to go looking for feature implementations. It makes it easier to debug and maintain someone else’s code, or even your own.

What Is Ember.js?

Ah, yes. It’s been a few pages since we even mentioned Ember, hasn’t it? As we established earlier, Ember is a cousin to SproutCore, a project which was, and is, an attempt to create a desktop-class software development kit (SDK) for the web platform.

JavaScript’s object-oriented model is pretty different from that of C++, Java, and other, more traditional interpretations. JavaScript employs a prototype model, a more dynamic, expressive method of implementing inheritance that seems to have a polarizing effect on developers. Some love it. Some hate it. Many, though, are confused by it or even unaware of it.

One of the major features of SproutCore 1.0 was a bolted-on object inheritance system that more closely resembled that of C++ or Java, offering object extension and more traditional class definitions. Where Ember and SproutCore differ most is that SproutCore also included a library of pre-built UI widgets, as many SDKs do. Just as an Objective-C developer can drop in a Cocoa dropdown widget rather than creating such a thing from scratch, SproutCore developers can drop in ready-made interface widgets with pre-built styling, functionality, and documentation. Ember forgoes including such a library in favor of encouraging you, the developer, to use the native library of your platform: HTML, JavaScript, and CSS.

In short, Ember.js is, as they put front and center on emberjs.com, “a framework for creating ambitious web applications.” It builds on jQuery, the ubiquitous JavaScript framework that smoothes out browser inconsistencies and adds a plethora of utility functions to JavaScript, and Handlebars, a library that offers HTML templating in JavaScript. Beyond the technology involved, Ember is a set of conventions for building robust, testable performant software. These conventions include everything from “here’s where this kind of code should be found within the project” to “here’s how you should name your classes.”

Why Choose Ember?

Ember is not the only solution, and it’s not for everyone. The concept of “convention over configuration” is a polarizing one in developer communities. If you like convention (if you’re a Ruby on Rails fan, for instance), you’ll probably love Ember. If you prefer to pare down your application stack and finely tune each piece, you may still enjoy Ember. Ember doesn’t prevent you from this kind of configuration, though it can make some of it more cumbersome than you might like.

Here are the main selling points of Ember:

  • Easy, fast, two-way data binding

  • What they call “developer ergonomics” (more on this in the next section)

  • Ember Data, which provides lots of ORM features and adapts to and abstracts away nearly any backend

  • Built-in URL/history management that’s tied to data and state automatically

  • Views built in HTML

That last bullet might not seem like a big deal, but if you’ve built an application in a framework that declares its views in JavaScript, rather than HTML, you can probably appreciate the difference. Declaring tag names, class names, inner text values, and other attributes in JavaScript is verbose, difficult to read, and requires someone who can “speak” JavaScript to write. Templates written in HTML can be created and edited by designers who know just enough HTML to be dangerous.

Developer Ergonomics?

You’ll see this phrase a lot in the documentation at emberjs.com: “Because this pattern is so common, it is the default for…” This indicates you don’t even need to type the code it’s describing; Ember will “just work” without it, employing the default behavior as though you’d specified it. As we’ll see in the next chapter, you can invoke a default route and a default controller just by instantiating an Ember application. With a single line of JavaScript (before minifying, wisenheimer) and a Handlebars template, Ember will fill in all the gaps with default objects, and you end up with a complete application.

What’s an ORM?

An object relational mapper is a piece of software that can translate data between different formats for serialization. For instance, say you have a data model in JavaScript, with JavaScript’s primitive data types: strings, numbers, and booleans. You want to persist your data in a MySQL database that wants to store that data in its supported types: CHAR, FLOAT, and BIT. An ORM knows how to translate your data to and from these differing formats so that you can serialize and de-serialize your data safely. ORMs have traditionally been a server-side technology, but Ember Data includes much ORM-like functionality on the client side. This allows you to separate the concerns of working with your data in your client-side application and persist your data to a long-term persistence solution (server, file storage, etc.). In fact, Ember Data allows you to write adapters that provide a consistent API, such that you could switch from using dummy data in the form of an in-memory JavaScript object in the early stages of the project, to using a MySQL service during development, to using a PostgreSQL service in production, without ever changing your model, view, or controller code.

What Is Ruby on Rails?

Ruby on Rails is a development platform made of two parts: Ruby, a programming language developed by Yukihiro “Matz” Matsumoto; and Ruby on Rails, a framework and set of conventions for building web applications in Ruby and a toolchain for the automated creation and maintenance of applications that adhere to those conventions, developed by David Heinemeier Hansson (DHH). Like Ember, Ruby on Rails espouses the “convention over configuration” approach. Its version of Ember’s “Because this pattern is so common, it is the default” is DHH’s “Look at all the things I’m not doing!” as seen in this Ruby on Rails demo. We’ll learn more about Ruby on Rails and why you might like to use it as your backend in Chapter 8.

What Is Node.js?

When Google set out to build its own web browser, way back in 2008 (or probably earlier, because that’s the year it was released), the team built its JavaScript engine, called V8, in such a way that it was, besides being quite fast, a great tool for hacking.  People figured out pretty quickly that you could use it to create all manner of applications outside a browser and written in JavaScript that could have many of the features of “native” applications, such as disk access or hardware inputs and outputs. Perhaps the most popular project to come out of this wizardry is Node.js, an application platform built on V8 that is particularly good at building scalable applications that run across multiple CPUs, due to its event-driven design. It’s not just for building web servers, but it has become quite popular for that purpose. And if you are building a web server with Node.js, you’ll probably want to take a look at…

Express.js

Express.js is a web-application framework for Node.js applications that does a lot of the heavy lifting in creating web applications.  Rather than writing an HTTP server from scratch, Express can provide you a lot of off-the-shelf functionality, while giving you plenty of opportunity to customize or overwrite the features you need.

Get Building Web Apps with Ember.js now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.