Towards Reactive Server Apps: a new hybrid web programming model pioneered by Blazor

Summary: Microsoft recently announced Razor Components (formerly Server-Side Blazor) will be shipping in .NET Core 3. Razor Components offer a new kind of programming model for the web, a blend of SPA and classic POST + Redirect + GET apps.

image

Reactive Server Apps: A fully-reactive web stack, where changes in the UI are automatically pushed down to the database, and changes in the database are automatically pushed up through to the DOM.

Imagine writing a web app that has virtually zero JavaScript, doesn’t need page reloads, and changes to the database are automatically and instantly reflected in the UI.

The Blazor project moves towards this ideal via its Razor Components (formerly Server-Side Blazor) programming model, what we might call the Reactive Server App model.

Today, most web apps fall into 2 categories:

  1. Classic POST + Redirect + GET (PRGs)
  2. Single Page Apps (SPAs)

POST+Redirect+GET is where you type in some data to a web page, hit submit button (POST), after a few seconds, a new page loads (Redirect) with the updated data (GET). You might call this classic web development.

Ordering tickets online is typically this kind of web app.

Single Page Apps (SPAs) are the thick-client model, only in the browser with JavaScript. You type in a URL, and the app loads. After that, everything seems to happen without page reloads: navigation, saving your data, loading data. This is because it’s all asynchronous; navigation and saving and UI interaction is done via asynchronous HTTP calls in the background.

Gmail is a Single Page App.

Blazor, the experimental framework intended to run C# in the browser via the new Web Assembly standard, is introducing a new hybrid model of web programming, what we might call Reactive Server Apps.

In v0.5, Blazor introduced Server-Side Blazor Apps. Where Blazor is Web Assembly runtime executing C# in the browser – a variant on SPA thick clients – Server-Side Blazor is a new programming model, where state lives on the server but is asynchronously pushed to the browser via web sockets.

Blazor went to v0.6 yesterday with a big announcement: Server-Side Blazor apps would be shipping separately from Blazor Web Assembly, shipping earlier (in .NET Core 3, due early 2019), and would be getting a new name: Razor Components.

How does this new web programming model work?

Like classic POST + Redirect + GET (PRG) apps, you writer server-side code (in our case, C# and .cshtml files). But unlike classic PRG apps, all the state is automatically shared between the server and the browser via web sockets.

So your app logic and state all exists on the server, but it’s automatically transferred to the browser. You click Save, and it feels like a SPA: things appear to happen instantaneously without POST + Redirect + GET reloads.

And because there’s a live connection between server and browser, apps no longer need to fetch data to display a page; the data can be pushed down to the browser in real time. This is why I call this hybrid model Reactive Server Apps.

If coupled with a database that supports reactive push notifications (e.g. RavenDB), this programming model may gain traction. I envision future web frameworks where the whole stack is reactive:

  1. Web app is reactive, pushing changes from the JavaScript data model to the DOM.
  2. Web server is reactive, pushing changes from the the server’s data model down to the browser.
  3. Database is reactive, pushing changes from the database to the web server.

Frameworks like React and Angular already do part #1: changes in the JavaScript model are automatically reflected in the DOM.

But these frameworks don’t do #2; instead they must poll the server for the latest data. And to do that, the server must poll the database.

Razor Components gives us step 2: the data model and state on the server is automatically pushed down to the browser. When the state or data changes, your server-side web app signals the browser and the corresponding browser components get asynchronously updated.

All that’s remaining is #3: a database that pushes changes to your web server. It just so happens we have such databases; I’m partial to RavenDB.

Imagine a server-side framework that has per-page state: here is the live data for /dashboard. As you’re looking at the page in your browser, changes to the data will appear automatically, because the database pushes changes to the server app, which pushes changes to the browser, which pushes changes to the DOM. The UI updates instantly and the developer didn’t have to do anything for that to happen.

Such a programming model has tangible improvements over both SPAs and PRGs.

Unlike SPAs, Reactive Server Apps would load fast because it’s essentially still a thin-client, no giant JS libraries or runtimes to pull in.

Reactive Server Apps would also be live: programmers don’t have to refetch data from the server to update the UI, and users experience immediate UI updates as the data changes; even if someone else changed the data they’re looking at.

Whereas SPAs rely heavily on Javascript, Reactive Server Apps will benefit from having more powerful programming languages to do the heavy lifting of development, easing development further.

And unlike PRGs, Reactive Web Apps don’t need page refreshes; the same benefit SPAs give. They also are “live” – changes to the database will flow to the DOM without having to re-query the database.

Downsides?

At least one downside is scalability; each app must have an open socket connection to the server. How well does this scale? This StackOverflow question seems to suggest it scales into the hundreds of thousands of concurrent users before having to add more servers.

Whether this model takes off or not is yet to be seen, but the idea is innovative. As a web developer, I’m excited to experiment with it.

RavenDB Studio 3.0, and why we moved from Silverlight to HTML5

Summary: A big step for RavenDB: a new HTML5 Studio. Plus, some thoughts on the move from Silverlight to HTML5 and our experience in the transition.

Yesterday, I pulled the covers off something I’ve been working on for a few months, something I’m very proud of.

RavenDB, the most popular NoSQL database in the .NET world, announced a brand new RavenDB Management Studio, Raven Studio 3.0, built from the ground up using HTML5 and modern web technologies. Yes, we’re moving away from Silverlight and onto HTML5.

Ayende and myself demoed the new Raven Studio just yesterday in a live webinar:

[youtube=http://www.youtube.com/watch?v=FNDKuiftKcc&w=448&h=252&hd=1]

This has been my pet project for the last few months, and it’s something I’m quite proud of! I believe this is a huge step forward for RavenDB (more on that in a minute), and the reception from the Raven community has been awesome, ego-stoking, and totally energizing.

The old Raven Studio was built in Silverlight. Some Silverlight fans have asked, why did we move to HTML5? Are we making a big mistake moving away from Silverlight and to HTML5?

No, on the contrary, we believe HTML5 is a damn good option.

  • The RavenDB community wants an HTML5 Studio. This has probably been the most-requested item from the RavenDB community. It came up multiple times in the Raven 3.0 Wishlist, it’s come up whenever Oren talks about the Studio, it comes up when we speak to the external developer community, heck, when I was in Israel for RavenDB training last year, one of the students brought it up right there in the Hibernating Rhinos office. Silverlight has served us well over the years, but Silverlight is a dying technology that our community doesn’t want to be tied to any longer. 
     
  • Silverlight tooling is a perceived barrier to Raven adoption. I speak at Code Camps and user groups, and when I speak on RavenDB, the love flows and the excitement grows…until I show Silverlight tooling. I get the raised eyebrow. “Silverlight? Oh. I see.” Others in the Raven community have reported this as well. For some, Silverlight is a stumbling stone. 
     
  • HTML5 is a step towards cross-platform Raven. RavenDB is the best NoSQL database for .NET. But, in time, we want Raven to spread her wings and be not just the best NoSQL solution for .NET, but the best NoSQL database, period. Moving to an HTML5 toolset is a step towards this goal. 
     
  • The software industry is moving away from plugins. Plugins like Silverlight added abilities you couldn’t do on the native web, such as audio, video, gaming, 2d drawing, documents, voice, and more. Plugins filled these gaps, but with HTML5, these gaps are disappearing. We don’t need Adobe Acrobat plugins anymore to view that high fidelity document. We don’t need Java applets anymore to run that simulation. We don’t need websites built entirely with Flash. And we don’t need Silverlight for Raven Studio. There is little reason today to build something in JavaFX, Flash, or Silverlight: the native web has supplanted them. Just as it’s rare – and often undesired – to see a Java applet out in the wild, so too it will be with Silverlight in the coming years.
     
  • The native web platform is a solid foundation for the future. Microsoft products come and go. 3 years ago, Microsoft was pushing Silverlight as the platform for line of business apps and islands of richness on the web. Today, Silverlight is prevented from running in the default browser of their newest operating systems.

    HTML, on the other hand, has been a stable, ever-evolving technology for decades, and because it is the very fabric of the web, things built in HTML live indefinitely. There’s a reason you can still visit and use the 17-year old Space Jam Website. Smile But your MS Silverlight app from last year? It won’t run even on the latest MS operating system’s default browser.

As a Silverlight developer who has built professional apps (e.g. 3M Visual Attention Service) and spoken at Code Camps and user groups on Silverlight, truth be told, Silverlight is a great developer platform. C# is an excellent language, Visual Studio probably the best development environment.

But, in the words of Miguel de Icaza, creator of Moonlight (open source, cross-platform Silverlight),

“I felt that Silverlight had a bright future, and that it could turn to fill an important void, not only for web development, but for desktop development in general.  And this was largely one of my motivators. I am very sad that Microsoft strategy cut the air supply to Silverlight.”

This, coupled with the mobile computing explosion and the software industry’s shift away from plugins, results in a sickly future for Silverlight and Silverlight apps.

RavenDB rocks, and we want the tooling to rock as well. Having our tooling tied to this technology was not an attractive proposition, and it was time for us to move on.

A new technology stack for Raven Studio 3.0

After much deliberation and considering all the options available to us, we moved off of Silverlight.

Instead of Silverlight, HTML5.

Instead of C#, TypeScript.

TypeScript is awesome. TypeScript is new language, a superset of JavaScript designed for building apps on the web. Silverlight fans will be happy to know it’s built by none other than Anders Heijlsberg, the much-respected language designer and author of C#.

In TypeScript, all JavaScript is valid TypeScript code, so it’s familiar to any web developer, but it gives us nice things like an optional, flexible type system, classes, modules, and enums, and features proposed for future versions of JavaScript, but compiles to plain old JavaScript that runs in every browser.

TypeScript tooling is Visual Studio, with all the nice debugging and refactoring that brings, but it can also be written in any text editor and debugged in any browser.

For infrastructure, because we wanted the look & feel of a web application, rather than a set of web pages, we opted to build a single page application (SPA). Durandal.js gives us exactly that: a nice means to load pages on demand and compose them into a cohesive web application.

For UI, Durandal uses Bootstrap for a consistent, pleasing aesthetic, and KnockoutJS for data binding and MVVM.

Using data binding, MVVM, and Durandal makes a great developer experience, one not too foreign to the MVVM stuff in Silverlight. (Indeed, the author of Durandal.js is the same author of the popular Silverlight MVVM framework Caliburn Micro.) Look at the code and judge for yourself; you’ll see classes separated out into small, logical view models, and a clean separation between view and logic.

What has been our experience moving to HTML5?

One immediate, measurable gain was performance:

  • Memory usage dropped from 140MB to 20MB.
  • Cold starts dropped from ~7s to ~2s.
  • Warm starts dropped from ~3s to ~1s.
  • General snappiness: XAML is rather heavyweight, and you’ll notice just moving around the application, loading your documents, collections, or editing – it’s all faster in HTML5. Snappy and responsive.
  • This doesn’t happen:
    image
  • This doesn’t happen either:
    image

A lot of the above we get for free simply by Doing Less Stuff™. No .xap files to download, no dlls to load, no CLR runtime to start, no plugin host process for the browser, no browser-to-plugin communication, no managed code to start executing.

This translates into faster start times and less memory usage.

Another free item we get is JavaScript and the blazing-hot modern JS browser runtimes. The major browsers – IE, Firefox, Chrome, Safari – are in a cut-throat competition to get the fastest JavaScript runtime, to squeeze every possible ounce of performance out of JavaScript. You’ll regularly see these browser vendors advertising their JS benchmarks as proof of performance improvement. This is a free win for the new HTML5 Raven Studio: as browser vendors continue to improve their engines in this cut-throat, cross-company competition of speed, Raven Studio will reap the performance improvements.

Moving to the native web platform fixes some plugin-induced workflow hiccups. For example, keyboard shortcuts: Silverlight and other plugins eat the keyboard. So say you’re got Raven Studio opened, and you want to open a new browser tab, so you hit CTRL+T. Surprise, nothing happens. Why? Silverlight ate your keyboard shortcuts, your browser never received them, and your workflow was just interrupted.

If you’ve ever used one of those old all-Flash websites, or full-page Java applets, you’ve probably noticed some things just don’t feel right. So it was with the old Silverlight Studio. Moving to HTML5 fixes these issues.

Conclusion

Transitioning out of the plugin ghetto and moving to HTML5 has been a delight, but more importantly, it’s good for RavenDB users as we move to a faster, more lightweight tool. It’s good for the future of RavenDB to have our tooling built on the solid rock of the native web.

I understand the Silverlight fans who are sad to see the old Silverlight Studio go. I’m a Silverlight fan myself, I understand their concerns. The most I can ask of you guys is to give us the opportunity to earn your trust. It will take time, but with a faster, more lightweight, stable tool that does what you need and gets out of your way, I believe that trust will be earned.

The new HTML5 Raven Studio is on GitHub and we’d love for you to give it a spin or even contribute to the code. I’m pleased to say we already have had a few contributions since it was released just yesterday. I’m proud of this work, and I really hope you guys enjoy it!

TypeScript, CoffeeScript, and the state of web development in late 2012

Summary: The problems facing web development today. Microsoft’s new TypeScript language, what problems it addresses, and what it leaves wanting.


Earlier this year, I predicted Microsoft would be utilizing their still-baking Roslyn compiler service to transform C# into targets besides IL, such as JavaScript. That prediction didn’t come true, but I was close: Microsoft is indeed getting into the compile-to-JavaScript games, but they’re doing so with a brand new language announced today, TypeScript.

JavaScript is a messy, powerful language.

The whole compile-to-JavaScript trend addresses a real problem in web development today: JavaScript just isn’t a great language for big web apps. Some argue it’s not a great language for anything besides quick DOM + event handler glue. And honestly, they kind of have a point.

Half baked, escaped the lab too early, leaving us silly things like implicit conversions for equality comparison. Quick, what’s the result of this?

foo = 0 == (100 + 23 === “123”)

If you guessed the boolean true, you’re right (I think!) but it shows kind of the trouble you get into when languages try to do too much for the developer.

But silly syntax puzzles aren’t the real reason JavaScript is bad for big apps.

No, it’s for a number of more deeply-seated reasons the difficulties arise when coding a large JS app with a team of developers:

  • The automatic, often accidental, inclusion in global scope. (The above snippet adds foo to the window object, woops!) This results in code littering the global namespace at best, and overwriting other code’s functionality at worst.
  • No modules or namespaces for code organization. In addition to contributing to the above problem, a lack of built-in modules means we have to resort to 3rd party libraries for dependency detection and loading. Often, developers will just take the easy route and load everything, resulting in web apps that load slowly and use excessive memory.
  • A 10-ways-to-do-this inheritance pattern that kinda sorta looks like classical inheritance but is really prototypal. Some codebases standardize on a 3rd party library (such as MooTools or Prototype), while other codebases become the Wild West of inheritance problems.
  • Without any types, refactoring and symbol analysis becomes painful. For example, want to find all callers of a function? Have fun with CTRL+F, and weed through who’s calling your function and who’s calling a function of the same name. Want to rename a property? CTRL+H and pray that no other code file has a property of the same name. And so on.

Plus other uglies like optional semicolons to end lines, resulting in production-level frameworks being filled with, in the words of JavaScript creator Douglas Crockford, “insanely stupid code.”

But one thing JavaScript is, is capable. It’s a functional, prototypal, object-oriented language. General purpose.

So rather than wait for JavaScript to slowly evolve through standards bodies and bickering, we build our own fast-evolving languages that compile down to JavaScript.

CoffeeScript: A (slightly) better JavaScript

At the time of this writing, the compiles-to-JavaScript language de jour is CoffeeScript: a superset of JavaScript that adds things like classes, and removes things like semicolons, parenthesis, and other staples of the C family of languages.

But CoffeeScript still lacks a proper compiler. Oh, sure, there’s the CoffeeScript compiler, but it’s not really a compiler. It can’t tell you if you’re passing the wrong type into a function. It can’t tell you if foo.Blah will error at runtime, because there’s no symbol analysis.

CoffeeScript also suffers from its straddle-the-fence stance on compatibility with JavaScript. Want to include parens? OK, valid! Want to exclude parens? OK, valid! While it sounds nice in theory, in practice you end up with an inconsistent codebase, and an awkward rule set about when optional syntax isn’t really optional.

And though CoffeeScript tried its hand at list comprehensions, it falls far short of what Python and C#/LINQ devs have been enjoying for years.

To make matters worse, there’s still no real standard library for JavaScript. Just a mash of tiny libraries that do things differently ($.map? or array.map?)

And finally, we still have terrible debugging support. Got Coffee? OK! How do I set a breakpoint on this CoffeeScript line? Silly developer, you can’t! You have to look at your Coffee, figure out which .js files were emitted, find those in your favorite web browser developer debugger tool, and break into that. Grahgghhlhlhlhsl.

End result? As of late 2012, we don’t have any great options for building big web applications. We need a language that supports symbol analysis (refactoring and the like), type error detection, modules, classes. We need a web development platform with a standard library. We need a web development platform that supports debugging in the language you authored.

Enter Microsoft’s TypeScript

TypeScript is a Microsoft attempt at solving these problems, in particular through the adding of types. It’s JavaScript with types.

Does it solve all the problems?

Too early to say.

It was announced only today, and I just downloaded the damn thing. At a glance, they solved the classes and modules problem. And by adding types and tooling support in Visual Studio, you can actually perform refactorings in your big codebase; something Java and C# developers have been enjoying for over a decade, but web developers have been suffering without.

It doesn’t appear to have a standard library – sorry, LINQ fans.

Nor does it appear to support debugging in Visual Studio.

UPDATE: The TypeScript compiler supports an experimental –sourcemap command line argument that generates a source map file. These source map files can then be used to debug TypeScript in the browser. I predict that Microsoft will use these source map files to integrate into Visual Studio’s debugging experience, likely through a special debugging browser similar to the existing Page Inspector.

So that answer for now appears to be, TypeScript is an incremental improvement upon CoffeeScript: types and modules and symbol analysis are a nice addition. We’re still missing some important things, namely, a standard library and a powerful source-language debugger. Until we get these things, web development is still a second class experience.

Apple: Please fix HTML5 on iOS

I’ve built an HTML5 audio player, Chavah Messianic Jewish Radio, that “works” on iOS.

By “works“, I mean, it plays the best it can on Apple’s crippled iOS <audio> implementation. At the time of this writing, this includes iOS 5, tested on iPhone 3 and 4, and iPad1 through iPad 3.

How is <audio> broken on iOS? Let me count the ways:

  • Apple does not let you play audio until user interaction. For me, this means detecting iOS, then showing the music as paused until the user clicks play. Their reasoning is that this will consume data and battery; in practice, though, it cripples web apps, forcing us to resort to platform-specific hoop-jumping  to get the web to work on your platform, Apple. It effectively stifles the evolution of the web in the same way IE did in the late 1990s.
  • Apple does not allow you to play concurrent audio files. This is a huge crippler for gaming apps that need to play sound effects, for example.
  • Apple doesn’t support OGG format. Patent-encumbered formats work, of course, but without support for free and open formats like OGG, Apple is effectively creating a long-term thorn in the side of the opened web.
  • Every dynamic <audio> element must receive user interaction. If you want to play successive sounds (one after another) without receiving user interaction for each one, you must use a single <audio> element, then do the iOS <audio> dance: set existingAudio.src, then call existingAudio.load(), then call existingAudio.play().
  • Audio events don’t fire unless Safari is in the fore. While audio will continue playing if the user switches to a different app, the .ended event won’t fire. This means it’s practically impossible to build a music player web app.

Apple, please, please, please give us better support for HTML5 in iOS Safari. Here are your action items, Apple:

  1. Let HTML5 audio work in the background.
  2. Support OGG.
  3. Support pre-loading audio.
  4. Support concurrent audio.
  5. Let us play audio without user interaction.

Do those things, Apple, you’ll be the industry leader in mobile HTML5 audio, everyone will emulate you, you’ll once again be leading the way, and HTML5 web apps will work best on your platforms. Wouldn’t that be good for Apple?

Yes, these features will use data and the battery, but native apps already do this, so why cripple web apps? Stop stifling the evolution of the web, and start being the leader. Make HTML5 <audio> a first-class citizen on iOS.