Joe Wells Engineering Fellow, Intuit
description
Transcript of Joe Wells Engineering Fellow, Intuit
Accelerate Your User Experience With Client-side
JavaScript
Lessons Learned From QuickBooks Online (QBO)
Joe WellsEngineering Fellow, Intuit
Intuit’s Mission:To improve our customers’ financial lives so profoundly…
they can’t imagine going back to the old way
CONSUMERSCONSUMERS SMALLBUSINESSES
SMALLBUSINESSES
ACCOUNTINGPROFESSIONALS
ACCOUNTINGPROFESSIONALS
A Premiere Innovative Growth Company
Employees
8,000+
Customers
45M
Global OfficesUS, UK, India,
Canada, Australia
Revenue
4.2B
Founded
1983Public 1993
INTU
Key Concepts Everything as a service Client-side frameworks to accelerate coding Designing services from the UI-first Plugin framework to unlock innovation Putting it all together: working with your experience designers
QBO Transformation
How QBO Used to Look (Demo)
How QBO Looks Today (Demo)
Under the Hood:Everything as a Service
QBO 2001-2010 Architecture
Server-Side Presentation
Single Data Center
JSP / Custom Java UI
QBO 2014 Architecture
Configurable Tax Model
Accounting Standards
eInvoicing & Payments
Global & AppStore Billing
Intuit Partner Platform
JMSMessaging
Client Rendering•HTML5•iOS•Android
Data-Only Transport
Developer API Services
Global Accounting Engine
World-Wide Data Centers
QBO TechnologiesClient Rendering•HTML5•iOS•Android
Developer API Services
Global Accounting Engine
World-Wide Data Centers
(FY’14)
logging
(FY’14)
(FY’14)
WAAData-Only Transport
Client-side Frameworks
Frameworks
You’re using require.js, right? And SASS/LESS please? What about two-way binding?
Example: Two-way Binding<div data-qbo-bind="visible: showDate"> <div>${nls.date}</div> <input class="dateInput" type="text" data-qbo-bind="value: date" data-dojo-type="qbo/widgets/DateTextBox”/></div>
visible: showDateHide/Show bound to this.model properties
${nls.date}Externalization of strings
value: date2-way value binding
UI-first Services
A common mistake is to design your services and then adapt your UI to those services.
This is backwards!
And it results in extra complexity in your client code.
What Not to Do: Services First
{ phoneNumber: “650-944-1111”, defaultTerms: “30 Days”, reportingMethod: “cash”, payrollPeriod: “weekly”, hasShipping: true}
/companyPreferences
{ date: “2014-06-26”, amount: 100.00, customer: “John” }
/invoice
Which ones apply to an Invoice? What is the logic to interpret them?
if (invoice.isNew && prefs.hasShipping) {
$(‘#shippingAddress’).show();
$(‘#shippingAmount’).show();
} else if (invoice.isEdit &&
!!invoice.shippingAddress) {
$(‘#shippingAddress’).show();
$(‘#shippingAmount’).show();
}
Repeated over dozens of preferences!
Alternative: UI First<input data-qbo-bind=
”value: shippingAddress, visible: hasShipping”
/>
<input data-qbo-bind=”value: shippingAmount, visible: hasShipping”
/>
{ hasShipping: true}
/invoice?txnId=-1
{ hasShipping: true}
/invoice?txnId=45
Our JSON{ "txnId" : -1, "txnTypeId" : 4, "date" : "2014-06-26", "txnProps" : { "hasShipping" : true, "hasDiscount" : true, "hasLocation" : true, "hasCharges" : true, "hasReimbExpense" : true, "taxReimbExpense" : false,
…
{ "txnId" : 101, "txnTypeId" : 4, "date" : "2014-06-26", ”amount" : 100.00, ”customer" : ”John”, "txnProps" : { "hasShipping" : true, "hasDiscount" : true, "hasLocation" : true, "hasCharges" : true, "hasReimbExpense" : true, "taxReimbExpense" : false,
…
Accelerated Workflow
Workflow – QA
Resource RequestResource Request
Serve json requests,
images, js, css, fonts, …
Serve json requests,
images, js, css, fonts, …
Response from QA ServerResponse from QA Server
Chrome browser QA Server
Workflow – Node.js localhost
Serve json requests,
images, js, css, fonts, …
Serve json requests,
images, js, css, fonts, …
Chrome browser QA ServerNode.js localhost
Resource RequestResource RequestLocal
Content?Local
Content? NoNo
Response from QA ServerResponse from QA Server
Response from Node.jsResponse from Node.js
Node.js localhost
var express = require("express");var httpProxy = require("http-proxy");var https = require("https");var fs = require("fs"); //load ssl cert
Plugin Frameworkto Unlock Innovation
Replaceable Plugin
Demo: Payroll in US and AU
Let’s Code One
Putting It All Together:Working With Your Designers
Launch, August 2013
August 2012
September 2012
October 2012
December 2012
December 2012
April 2013
June 2013
Launch, August 2013
Key Concepts Everything as a service Client-side frameworks to accelerate coding Designing services from the UI-first Plugin framework to unlock innovation Putting it all together: working with your experience designers