Вы находитесь на странице: 1из 11

NeWith the release of Exchange Server 2016 Microsoft took the opportunity to

simplify some of the architecture complexity that was present in previous versions.
It also includes new features which make communication and collaboration easier.
Microsoft has changed the way Exchange deployment has been done for the last few
releases. Implementation is now easier, the configuration is simpler, and upgrading
has fewer steps. The number of servers required have been reduced, as have
licensing costs and infrastructure requirements. Hybrid deployments are also much
easier using on premise and Exchange Online or Office 365, which can further reduce
the required on premise infrastructure.

Microsoft simplified the architecture by removing the Exchange 2013 Client Access
Server role and added it as a service on the Exchange 2016 Mailbox Server Role. Now
there is just one Exchange 2016 Mailbox Server role with Client Access and
Transport services included on it. The Edge Transport Server is retained from the
previous versions of Exchange and provides inbound and outbound mail routing as
well as anti-spam, antivirus, and content connection filtering via address
rewriting to protect internal servers.

The new Microsoft Exchange Server 2016 Building Block Architecture is presented in
Figure 1. The Exchange Server 2016 mailbox servers on the Internal network are the
points of communication for all clients, Active Directory and all other services
that communicate with Exchange server. Internet client communication is also routed
to the Exchange mailbox server. It is not recommended you expose the Exchange
Client Access server directly on the Internet. Traffic should be routed via a
LoadMaster appliance acting as a reverse proxy. The Edge Transport server should
also be positioned in the perimeter network where it can help protect the internal
mailbox servers. DNS MX records should be configured to use the Edge Transport
server, or to any hosted solution like Microsoft Online protection which can then
forward mail to the Edge Transport server.

At Airbnb, weve learned a lot over the past few years while building rich web
experiences. We dove into the single-page app world in 2011 with our mobile web
site, and have since launched Wish Lists and our newly-redesigned search page,
among others. Each of these is a large JavaScript app, meaning that the bulk of the
code runs in the browser in order to support a more modern, interactive experience.

This approach is commonplace today, and libraries like Backbone.js, Ember.js, and
Angular.js have made it easier for developers to build these rich JavaScript apps.
We have found, however, that these types of apps have some critical limitations. To
explain why, lets first take a quick detour through the history of web apps.
JavaScript Grows Up

Since the dawn of the Web, the browsing experience has worked like this: a web
browser would request a particular page (say, http://www.geocities.com/), causing
a server somewhere on the Internet to generate an HTML page and send it back over
the wire. This has worked well because browsers werent very powerful and HTML
pages represented documents that were mostly static and self-contained. JavaScript,
created to allow web pages to be more dynamic, didnt enable much more than image
slideshows and date picker widgets.

After years of advances in personal computing, creative technologists have pushed


the web to its limits, and web browsers have evolved to keep up. Now, the Web has
matured into a fully-featured application platform, and fast JavaScript runtimes
and HTML5 standards have enabled developers to create the rich apps that before
were only possible on native platforms.
The Single-Page App

It wasnt long before developers started to build out entire applications in the
browser using JavaScript, taking advantage of these new capabilities. Apps like
Gmail, the classic example of the single-page app, could respond immediately to
user interactions, no longer needing to make a round-trip to the server just to
render a new page.

Libraries like Backbone.js, Ember.js, and Angular.js are often referred to as


client-side MVC (Model-View-Controller) or MVVM (Model-View-ViewModel) libraries.
The typical client-side MVC architecture looks something like this:

Screen Shot 2013-11-06 at 5.21.00 PM

The bulk of the application logic (views, templates, controllers, models,


internationalization, etc.) lives in the client, and it talks to an API for data.
The server could be written in any language, such as Ruby, Python, or Java, and it
mostly handles serving up an initial barebones page of HTML. Once the JavaScript
files are downloaded by the browser, they are evaluated and the client-side app is
initialized, fetching data from the API and rendering the rest of the HTML page.

This is great for the user because once the app is initially loaded, it can support
quick navigation between pages without refreshing the page, and if done right, can
even work offline.

This is great for the developer because the idealized single-page app has a clear
separation of concerns between the client and the server, promoting a nice
development workflow and preventing the need to share too much logic between the
two, which are often written in different languages.
Trouble in Paradise

In practice, however, there are a few fatal flaws with this approach that prevent
it from being right for many use cases.
SEO

An application that can only run in the client-side cannot serve HTML to crawlers,
so it will have poor SEO by default. Web crawlers function by making a request to a
web server and interpreting the result; but if the server returns a blank page,
its not of much value. There are workarounds, but not without jumping through some
hoops.
Performance

By the same token, if the server doesnt render a full page of HTML but instead
waits for client-side JavaScript to do so, users will experience a few critical
seconds of blank page or loading spinner before seeing the content on the page.
There are plenty of studies showing the drastic effect a slow site has on users,
and thus revenue. Amazon claims that each 100ms reduction in page load time raises
revenue by 1%. Twitter spent a year and 40 engineers rebuilding their site to
render on the server instead of the client, claiming a 5x improvement in perceived
loading time.
Maintainability

While the ideal case can lead to a nice, clean separation of concerns, inevitably
some bits of application logic or view logic end up duplicated between client and
server, often in different languages. Common examples are date and currency
formatting, form validations, and routing logic. This makes maintenance a
nightmare, especially for more complex apps.

Some developers, myself included, feel bitten by this approach its often only
after having invested the time and effort to build a single-page app that it
becomes clear what the drawbacks are.
A Hybrid Approach
At the end of the day, we really want a hybrid of the new and old approaches: we
want to serve fully-formed HTML from the server for performance and SEO, but we
want the speed and flexibility of client-side application logic.

To this end, weve been experimenting at Airbnb with Isomorphic JavaScript apps,
which are JavaScript applications that can run both on the client-side and the
server-side.

An isomorphic app might look like this, dubbed here Client-server MVC:

Screen Shot 2013-11-07 at 10.29.32 AM

In this world, some of your application and view logic can be executed on both the
server and the client. This opens up all sorts of doors performance
optimizations, better maintainability, SEO-by-default, and more stateful web apps.

With Node.js, a fast, stable server-side JavaScript runtime, we can now make this
dream a reality. By creating the appropriate abstractions, we can write our
application logic such that it runs on both the server and the client the
definition of isomorphic JavaScript.
Isomorphic JavaScript in the Wild

This idea isnt new Nodejitsu wrote a great description of isomorphic JavaScript
architecture in 2011 but its been slow to adopt. There have been a few
isomorphic frameworks to spring up already.

Mojito was the first open-source isomorphic framework to get any press. Its an
advanced, full-stack Node.js-based framework, but its dependence on YUI and Yahoo!-
specific quirks havent led to much popularity in the JavaScript community since
they open sourced it in April 2012.

Meteor is probably the most well-known isomorphic project today. Meteor is built
from the ground up to support real-time apps, and the team is building an entire
ecosystem around its package manager and deployment tools. Like Mojito, it is a
large, opinionated Node.js framework, however its done a much better job engaging
the JavaScript community, and its much-anticipated 1.0 release is just around the
corner. Meteor is a project to keep tabs on its got an all-star team, and its
raised $11.2 M from Andreessen Horowitz unheard of for a company wholly focused
on releasing an open-source product.

Asana, the task management app founded by Facebook cofounder Dustin Moskovitz, has
an interesting isomorphic story. Not hurting for funding, considering Moskovitz
status as youngest billionaire in the world, Asana spent years in R&D developing
their closed-source Luna framework, one of the most advanced examples of isomorphic
JavaScript around. Luna, originally built on v8cgi in the days before Node.js
existed, allows a complete copy of the app to run on the server for every single
user session. It runs a separate server process for each user, executing the same
JavaScript application code on the server that is running in the client, enabling a
whole class of advanced optimizations, such as robust offline support and snappy
real-time updates.

We launched an isomorphic library of our own earlier this year. Called Rendr, it
allows you to build a Backbone.js + Handlebars.js single-page app that can also be
fully rendered on the server-side. Rendr is a product of our experience rebuilding
the Airbnb mobile web app to drastically improve pageload times, which is
especially important for users on high-latency mobile connections. Rendr strives to
be a library rather than a framework, so it solves fewer of the problems for you
compared to Mojito or Meteor, but it is easy to modify and extend.
Abstraction, Abstraction, Abstraction

That these projects tend to be large, full-stack web frameworks speaks to the
difficulty of the problem. The client and server are very dissimilar environments,
and so we must create a set of abstractions that decouple our application logic
from the underlying implementations, so we can expose a single API to the
application developer.
Routing

We want a single set of routes that map URI patterns to route handlers. Our route
handlers need to be able to access HTTP headers, cookies, and URI information, and
specify redirects without directly accessing window.location (browser) or req and
res (Node.js).
Fetching and persisting data

We want to describe the resources needed to render a particular page or component


independently from the fetching mechanism. The resource descriptor could be a
simple URI pointing to a JSON endpoint, or for larger applications, it may be
useful to encapsulate resources in models and collections and specify a model class
and primary key, which at some point would get translated to a URI.
View rendering

Whether we choose to directly manipulate the DOM, stick with string-based HTML
templating, or opt for a UI component library with a DOM abstraction, we need to be
able to generate markup isomorphically. We should be able to render any view on
either the server or the client, dependent on the needs of our application.
Building and packaging

It turns out writing isomorphic application code is only half the battle. Tools
like Grunt and Browserify are essential parts of the workflow to actually get the
app up and running. There can be a number of build steps: compiling templates,
including client-side dependencies, applying transforms, minification, etc. The
simple case is to combine all application code, views and templates into a single
bundle, but for larger apps, this can result in hundreds of kilobytes to download.
A more advanced approach is to create dynamic bundles and introduce asset lazy-
loading, however this quickly gets complicated. Static-analysis tools like Esprima
can allow ambitious developers to attempt advanced optimization and metaprogramming
to reduce boilerplate code.
Composing Together Small Modules

Being first to market with an isomorphic framework means you have to solve all
these problems at once. But this leads to large, unwieldy frameworks that are hard
to adopt and integrate into an already-existing app. As more developers tackle this
problem, well see an explosion of small, reusable modules that can be integrated
together to build isomorphic apps.

It turns out that most JavaScript modules can already be used isomorphically with
little to no modification. For example, popular libraries like Underscore,
Backbone.js, Handlebars.js, Moment, and even jQuery can be used on the server.

To demonstrate this point, Ive created a sample app called isomorphic-tutorial


that you can check out on GitHub. By combining together a few modules, each that
can be used isomorphically, its easy to create a simple isomorphic app in just a
few hundred lines of code. It uses Director for server- and browser-based routing,
Superagent for HTTP requests, and Handlebars.js for templating, all built on top of
a basic Express.js app. Of course, as an app grows in complexity, one has to
introduce more layers of abstraction, but my hope is that as more developers
experiment with this, there will be new libraries and standards to emerge.
The View From Here
As more organizations get comfortable running Node.js in production, its
inevitable that more and more web apps will begin to share code between their
client and server code. Its important to remember that isomorphic JavaScript is a
spectrum it can start with just sharing templates, progress to be an entire
applications view layer, all the way to the majority of the apps business logic.
Exactly what and how JavaScript code is shared between environments depends
entirely on the application being built and its unique set of constraints.

Nicholas C. Zakas has a nice description of how he envisions apps will begin to
pull their UI layer down to the server from the client, enabling performance and
maintainability optimizations. An app doesnt have to rip out its backend and
replace it with Node.js to use isomorphic JavaScript, essentially throwing out the
baby with the bathwater. Instead, by creating sensible APIs and RESTful resources,
the traditional backend can live alongside the Node.js layer.

At Airbnb, weve already begun to retool our client-side build process to use
Node.js-based tools like Grunt and Browserify. Our main Rails app may never be
entirely supplanted by a Node.js app, but by embracing these tools it gets ever
easier to share certain bits of JavaScript and templates between environments.

You heard it here first within a few years, it will be rare to see an advanced
web app that isnt running some JavaScript on the server.
Learn More

If this idea excites you, come check out the Isomorphic JavaScript workshop Ill be
teaching at DevBeat on Tuesday, November 12 in San Francisco, or at General
Assembly on Thursday, November 21. Well hack together on the sample Node.js
isomorphic-tutorial app Ive created to demonstrate how easy it really is to get
started writing isomorphic apps.

Also keep tabs on the evolution of the Airbnb web apps by following me at
@spikebrehm and the Airbnb Engineering team at @AirbnbEng.
Want to work with us? We're hiring!

Published in Code
November 11, 2013 by Spike Brehm
30 Comments

30 Comments

Dustin Hoffman
November 12, 2013 at 12:11 am

This is awesome, it definitely sets the stage for a future where more
route/render assets are shared between your client app and your server app.

Its good to be putting more thought into this, I think as a community weve
(perhaps too eagerly) jumped on the single-page site bandwagon as
Backbone/Ember/Angular rise up, but then we all feel the same burn of SEO &
performance. The happy medium is being locked in on, and that is fantastic.
Chase Adams
November 12, 2013 at 12:53 am

Great article! Its a hard line to walk, trying to keep things isomorphic.

What are your thoughts on using something like PhantomJS to create snapshots
that are served to the robots that are crawling? An example of how that works:
http://blog.christoffer.me/post/2013-04-20-how-to-make-spa-websites-more-search-
friendly/#.UoF7JpRmtbs.

Also, the name and email fields on this page are set to display:none. I had to
disable the style in the inspector to post. Hope that helps!
Jason
November 12, 2013 at 11:14 pm

I didnt think this was a very good post.


The Trouble in Paradise leaves much to be desired, including real perf data in
the Performance section.
The Twitter anecdote was just that, an anecdote.
Also, commenting on this article is very difficult to do. Your required form
fields are hidden.
Philippe
November 13, 2013 at 7:55 am

Thanks for the article. Im a bit surprised to read in the subject you consider
its the future of web apps, and later in the Trouble section: This makes
maintenance a nightmare, especially for more complex apps. This sound incompatible
to me.
Stanford Rosenthal
October 9, 2014 at 6:42 pm

That section is referring to standard single-page apps. This article is


about isomorphic apps, which aims to solve these problems.
Casen davis
December 3, 2014 at 11:08 am

Hi Stan
Agelos Pikoulas
November 14, 2013 at 9:14 am

Isomorphic JavaScript (from the Greek {isos: equal, morph: shape}) is


the actualization of the write once, run everywhere mantra, in steroids.

Its a huge opportunity for systems to blur the roles of who is the client and
the server and what gets rendered where, when and why. It leads a path to a true
dynamic breed of apps & servers, that know what needs to be pre-rendered or what
should be lazy loaded / evaluated / rendered etc.

But flexibility in code modularization and dynamic loading and evaluation of


modules or module/resources bundles is more crucial than ever. And its the point
where Javascript doesnt have one module system, but many. The most prominent being
AMD (i.e RequireJS) and CommonJS (i.e nodejs). Both AMD and CommonJS are
incompatible in syntax and semantics, one targeting the browser & the other the
server, with many hacks or boilerplates that allow each to run on the other
runtime eg like UMD.

Towards this end I developed uRequire which bridges AMD and CommonJS, mainly as
a UMD converter and bundler, but later made it into an in-memory resource converter
pipeline i.e a build system that is aware of dependencies.

I envision that a builder like uRequire could evolve into a dynamic code
serving system, bundling and/or evaluating code & resources on demand. Cause if you
can build hotels, why not serve tourists ?
Ido Green
November 14, 2013 at 6:21 pm

Thank you!
Its a great article that cover some of the main challenges we have today on
the web with modern web apps.
nide
November 14, 2013 at 6:42 pm

With emscripten https://github.com/rfk/emscripten you can run client side on


any platform. To me idea of isomorphic python with django seems much more
interesting.
lolmaus
November 15, 2013 at 12:14 am

This post is not complete without mentioning DerbyJS.


vmakhaev
November 15, 2013 at 6:20 am

Why you said nothing about DerbyJS?


Davide Callegari
November 15, 2013 at 2:40 pm

I started working on heavy js apps in 2008 and Im quite sick of having to deal
with 231 js libraries.
At first it was fun and exciting, but now it isnt anymore.
Please give me a good solution (framework) that just works ^^
Greg
December 20, 2013 at 9:37 am

Meteor.js ?
Dan
June 5, 2014 at 8:13 pm

Have you actually dealt with multiple Javascript libraries?


Cosmin
November 15, 2013 at 3:33 pm

Great article!

However, consider the following scenario: I have a code-generator sitting on


the server, written in Java for example, which produces HTML which further uses a
JS framework which does things like client-side validation, formatting, i18n and
even DOM-manipulation.

Is this Isomorphic approach valid for this type of application described


earlier? I mean, should we consider re-factoring our code in order to benefit from
this type of approach?
Nathan Tate
November 15, 2013 at 4:32 pm

Ive been working on an isomorphic nodejs framework built on express that


automatically generates a front-end sdk of your back-end code. I could really use
some feedback: https://github.com/RedRabbitDevelopment/ez-ctrl
Georgi
December 3, 2013 at 2:33 pm

Wanted to share few thoughts with you because Ive been user of AirBnb since
years, and apart from that, have learned a lot of your source code.

Right now Im rewriting the entire administration panel of a hosting company


and having the same issues and the main solution was the hybrid approach.
Could say Ive found myself also with some problems related with routing,
rendering and fetching, but mostly with the i18n, i18l and some documentation
related with specific frameworks.

Routers based on user language, render fetched data to specific localization


and most important: single age app with an unlimited MVVCs took me a lot of time
and investigation. Most of the tutorials and examples are based on simple single
page calls and requests, and some of them even arent working.

Of course, one of the things not important that much for internal apps is the
SEO, but for website accessible by search engines, is top priority. And once again,
the people behind most of the tutorials doesnt care.

Great article, just from personal point of view, examples are much better if
are online and live. People use to understand better the concepts when they see it
moving :)
Nuno Pato
December 10, 2013 at 3:25 pm

Good post but be carefully with the nomenclature used. When you say single-
page app that can also be fully rendered on the server-side you mean template
rendering, not graphical rendering.
Gang Yang
January 21, 2014 at 4:36 pm

All what you desire is ready to use in Flash Platform.

Flash is controlled by Adobe? How about IE/Chrome? are they open source?
jhnns
February 2, 2014 at 2:05 pm

Thanks for sharing your thoughts on isomorphic javascript. Im writing (or


better: trying to write) isomorphic web-apps for two years now and came to almost
the same conclusions and ideas youve pointed out. But there are still many
obstacles in the way and I think we still dont know exactly how to write an
application that is able to run in different environments.

One conclusion I came to is that large monolithic frameworks like meteor dont
tend to have the flexibility to adopt different environments. Its important to
note that there is not just one single client, you could have several clients for
different environments (desktop, mobile web-apps, phonegap).

A modular approach is more flexible and allows the application to adopt these
environments. But in this case its up to the developer to loosely couple all
components in order to avoid structures like if (isServer) { } else { } which
is one of the most challenging tasks.

By the way: For everyone who is trying to cope with different module styles and
dynamic code loading there is webpack. Its capable of AMD and CommonJS and
provides mechanism to split the code into multiple bundles. Its also possible to
define loaders which transform the module so it can be shipped to the browser (e.g.
css-loader, less-loader, jade-loader, etc.).
Prem Mohan
April 22, 2014 at 7:26 pm

When are you going to have another Isomorphic JavaScript workshop? I have been
doing Web UI development from the early days of JavaScript and seen its evolution
exactly as you chronicle here. My last application was done using single page UI
framework using Backbone and later Sencha ExtJS. The idea of using JS on both
client and server has occurred to me several time and led by I played around a bit
with Node.js. Would be great to know more on this in your next workshop.

Thx.
Sebastian Patten
September 5, 2014 at 9:51 pm

Its definitely an interesting idea! I built an architecture in 2011 based off


the notion of 0 data transformations between client and server side. It ran on the
following: UI changes picked up by Knockout.js which changed the underlying data
model. Data model changes caused Socket.IO to fire an event in the format of JSON
DTOs. Node.js handled the events and re-validated the DTOs in the same domain
object JavaScript file that is used on the client side. The JSON was then saved
into MongoDB as JSON.
Yannik
September 9, 2014 at 8:50 pm

In my understanding of a good web application, I would draw the single-app


model like this:

Server (Nginx, Apache)


|
v
Client (javascript)-> API (PHP, Ruby, Python, Java)

My understanding of this isomorphic model is that you write once a


model+controller+view for both the server and the client side, right? Then, Ive
been looking for an isomorphic-model intensively and I think there is nothing
ready yet: there is too many security issues. Probably the best bet now is to use
generators: you write once a controller+model (e.g. an Angular controller + the
route + the promise) and a Yeoman generator would derive the other controller for
Ember (or whatever). Or the opposite.
Aureliano
October 24, 2014 at 7:18 pm

I am working on an isomorphic framework based on rhino and requirejs. At its


current state I am able to run d3 server-side to generate things. You may want to
check it out. It is at https://bitbucket.org/aurelito/sandro/
Kurtis Kemple
November 21, 2014 at 3:47 pm

Great article, I have been working on a flux architecture app and looking for
something to handle the routing, I will look into Director, thank you for sharing
the example project as well, great work and very beneficial!!
catherine alexander
December 6, 2014 at 2:33 pm

As you can probably tell from my user ID, I am not a software engineer. But I
am hoping someone here can help me with the Verification step in airbnb. I cannot
get the site to accept my iPhone picture of my drivers license. So I am in limbo.
I cannot make any changes to my listing I just get kicked back to the Verify
page. I have tried over 8 times to upload my .jpg of my drivers license. Any
ideas?
Blabla
January 19, 2015 at 7:12 am

Well, you achieve better performance with client server rendering:


http://www.onebigfluke.com/2015/01/experimentally-verified-why-client-
side.html?m=1
Noj Vek
February 2, 2015 at 12:02 pm

has a nice description has a typo. The h of has should be in the tag. I
wonder if anyone at airbnb uses ReactJS
Doug
February 27, 2015 at 6:45 am

Still loving the old fashioned way. Ive developed some small apps with
Backbone, had that hurray feeling, happy with that request less working on the
client, but in the end something stood missing. I found enough to serve a page to
the client as fast as possible, no matter is it on client or coming from the
server. Pjax and jquery simple ajax calls does the work for me. Serving pages from
ruby or php for small/midsize sites, without team up with 40 engineers to do some
magic in node still looks a good idea. Im happy to hear about new technologies or
techniques, but sometimes the story told as the future is here. Work arounds for
SEO, server side rendering for crawlers What about the crawlers, why they dont
care so much about crawling API-s or URL-s?
Rick Wong
March 10, 2015 at 4:21 am

Thanks for sharing AirBnBs insights on this topic!

Last week I pushed my own isomorphic React starterkit to GitHub, where it was
trending:
- https://github.com/RickWong/react-isomorphic-starterkit
The starterkits focused on the build tools and overall ease-of-use. You can
get started in less than 5 minutes. The included example showcases how the server &
client work together elegantly to produce the page. The goal of the starterkit is
to enhance productivity so theres one single cli command to watch and rebuild both
the server with auto-reloads, and client with hot (instant) code updates.
Everything happens automatically on-save.
Check it out, it just works. Im looking for feedback.

Comments are closed.

Code
Tech Talks
Open Source
News
Data
More Airbnb blogs
Airbnb blog
Public Policy
Design
We're hiring
Find Us at
Twitter
Github
Facebook
Google+
Twitter
YouTube
RSS

Airbnb, Inc
About Airbnb

Airbnb is a global community marketplace that connects travelers seeking


authentic, high-quality accommodations with hosts who offer unique places to stay.
Find more in our Sitemap

Airbnb, Inc.
3.3k
Shares
Facebook1.2kLinkedIn727Google+495TwitterEmailSumoMe

Вам также может понравиться