At the origin there was a monolith. Behind a successful startup often lies a single technology application (Java, Rails, etc.) that grows until it hardly scales with the number of customers and likewise its development process as developers increase. A consolidated strategy on the back-end is to progressively slice the monolith into micro-services. A dual solution on the front-end is to gradually extract HTML, CSS and JavaScript code into a Single Page Application, applying some techniques like the ones I've been maturing during my experience in Workshare.
2. Agenda
● a few definitions
● my experience in Workshare
● some take aways
● current state and future
● what’s your experience?
3. Your traditional web application built
on server side technology, whether
MVC or component based...
A definition for a “Multi Page Application”
4. “A single-page application (SPA) is a web application or
web site that fits on a single web page with the goal of
providing a more fluent user experience similar to a
desktop application.
In a SPA, either all necessary code – HTML, JavaScript,
and CSS – is retrieved with a single page load.”
Single Page Application on WikiPedia
5. “Code refactoring is the process of
restructuring existing computer code –
changing the factoring – without changing
its external behavior.
Refactoring improves nonfunctional
attributes of the software.”
(Code) Refactoring on WikiPedia
6. A refactoring tale: Workshare
1999
Workshare
Doc Comparison and
Metadata Cleaning
Desktop Products
Apr 2012
SkyDox acquisition
Document Sharing SaaS
Ruby monolith #1
aka Cirrus
Nov 2012
IdeaPlane acquisition
Enterprise Social
Network
Java monolith
aka Social
Dec 2014
Dealroom acquisition
Legal Transaction WFE
Ruby monolith #2
aka Transact
now
Scaling
microservices on BE
SPA on FE
7. Cirrus
● Typical Rails
Application
● Does a Lot :)
○ including REST API!
● Does Too Much :(
● “Leverages”
ActiveRecord!
● You know the end of
the story...
9. The Masterplan!
● a spike on a SPA
○ called “supernova-ui”
○ validate we can do JavaScript
● phasing out all server side tech
producing front-end code
● migrate backend to microservices
○ Cirrus already provides JSON API
○ Social doesn’t and becomes first
microservice: Groups API
14. Node allows front-end developers to take control
● pick your favourite javascript build
template
○ ex. a yeoman generator
● launch a development server
○ ex. via grunt-contrib-connect
● proxy your current web app or API
○ ex. via grunt-connect-proxy
● overlay your changes
18. Define your main application layout, client-side
● you will need some basic API
○ user API
○ account API
● application layout
○ topbar
○ sidebar
○ user menu
○ content
● a good candidate for offline
21. Authentication is complex, you don’t want to break it!
● typical web form login
● CSRF protection
● authentication via cookie
● support auth cookie on API
● single-sign on flows
● vanity domains
23. iframe are ugly but can be useful...
● content access when on same origin
● native API to communicate
○ window.postMessage
● easy to detect
○ window === window.parent
● listen to URL/hash changes
24. is a backend dev available? cool!
● create a custom page format
○ (ex. nova)
● serve a naked version of your page
with just the main content
○ in Rails :layout => false
● in your url_helper modify your href to
send a message via javascript to
your parent application
25. isn’t a backend dev available? oh no!
● load iframe as hidden
● hide application chrome and anything
which is not your main content
● patch CSS if necessary
● patch links to route on SPA
● repeat on URL/hash change
27. No refactoring without a proper test suite!
● Robot Framework
○ API tests
○ FE tests via WebDriver
● BDD style test definitions
● Re-use with minimal changes
○ if element selector don’t change!
○ adapt custom keywords
■ Navigate To (new URLs)
■ Locate Element (switch to iframe)
29. ● map existing URLs you want to keep
● define your strategy to serve your SPA
○ on a subcontext /new-ui
○ on the root
■ via a custom header x-new-ui=true
■ on a different server
● proxy APIs and iframe pages
○ keep same origin
○ no need for CORS headers
It’s deployment time! From Node to Apache/nginx
31. Evolve existing multi page URLs to single
● inject CSS from parent window
● build views in your SPA
● instantiate in multi page
● inject in parent DOM
● it’s really hard but a temporary
workaround until APIs are
available!
33. 3 years later and 42 microservices after...
● refactoring well is a long and
sloooow process...
● ...but we release weekly!
● the SPA approach allows iterating
much faster
● also designers with front-end skills
can easily build prototypes!
34. What didn’t work so well
● login pages must be fast!
● FOUC (flash of unstyled content)
● existing “SPAlets” taking full
control of the page (we had some
GWT ones) are hard to integrate
● IE9 and hash URLs
● bundle JavaScript in chunks
35. Disclaimer! Problems we didn’t have to solve
● it’s a web application, not a website
● URLs are forever
● SEO
○ googlebot crawls #! URLs
○ what about the others?
● browsers with JavaScript disabled
● IE less than 9
● first render speed
● should we go isomorphic?
37. Frontend and Backend teams working together
the Web Squad builds
the web frontend user
interface...
…but the Cirrus Squad
provides the API our
features build upon!