SlideShare une entreprise Scribd logo
1  sur  112
Télécharger pour lire hors ligne
Advanced I/O
in browser
Eugene Lazutkin, 5/2/2017, ClubAjax, Dallas, TX
@uhop, www.lazutkin.com
Outline
Prototype an I/O library.
What we have,
and what is wrong with it.
Libraries!
What do Angular and React do?
Back to the board!
Advanced I/O
Browser
Now provides all low-level stuff.
We can (without jQuery!):
Search by selector.
Calculate geometry.
Manipulate CSS classes.
Much more!
How about I/O?
Stone age.
We still need to use libraries.
Let’s design an ideal solution.
Then compare it with what we have.
The ideal
HTTP
Simple text format.
The same is used by HTTPS.
Covered by standards.
Uses verbs and status codes.
Consists of headers and body.
HTTP request
POST /api HTTP/1.1
Host: localhost:8000
Connection: keep-alive
User-Agent: ...user agent string...
Content-Type: application/json
Accept-Encoding: gzip, deflate
Cookie: io=JSwSxqG0tIMQ_ZtZAABl
...body, if needed...
HTTP response
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 18193
Date: Sun, 30 Apr 2017 23:52:36 GMT
...body, if needed...
Design decisions I
Return Promise.
Helps with composability.
A way from the callback hell.
Pack all request parameters together.
Use raw {} for simplicity.
We can manipulate it.
Design decisions II
Be smart about response
Users want to deal in terms of data:
Send data
Receive data
In most cases a response object is not
needed.
Design decisions III
Be smart about response
Sometimes we need a response:
To read status and headers.
Cater for most common cases:
JSON in/out should be simple.
The rest should be possible.
Design decisions IV
We interpret status code.
4XX and 5XX are bad statuses.
204 is good, but no response.
⇒ undefined.
Design decisions V
We interpret MIME.
If you don’t set:
Content-Type
Accept-Type
⇒ application/json
Design decisions VI
Recognize special data:
FormData — forms.
Document — XML.
ArrayBuffer, Blob.
Design decisions VII
Form query:
Bad:
url: '/abc/?name=' + name +
'&age=' + age
Good:
url: '/abc',
query: {name: name, age: age}
XKCD: Exploits of a Mom
https://xkcd.com/327/
Don’t be a Bobby Tables!
Design decisions VIII
Different types for different errors.
Use instanceof to make a choice.
Errors: wrong request, timeout, bad
status.
Result
io({
url: url,
method: 'POST',
headers: {
'X-Custom-Header': 'abc'
},
data: data // JSON
}) // then() and catch()
Result: POST JSON example
io(req).then(result => {
console.log(result.name);
}).catch(res => {
if(res instanceof io.FailedIO) {}
if(res instanceof io.TimedOut) {}
if(res instanceof io.BadStatus) {
console.log(res.xhr.status);
}
});
How we interpret result?
We know Content-Type.
application/json ⇒ JSON.
application/xml ⇒ XML.
MIME types are covered by RFCs.
We can map them to whatever.
Or return a string or a buffer.
Design: helpers I
We can provide helpers for verbs:
io.get (url, queryData);
io.head (url, queryData);
io.post (url, data);
io.put (url, data);
io.patch (url, data);
io.delete (url, data);
Design: helpers II
url is a string, or an object like for io().
queryData and data are optional.
A helper overrides a verb.
Design: helpers III
// url as an object? for REST:
var opts = {url: url, headers: headers};
io.get(opts);
io.put(opts, data);
io.patch(opts, data);
io.delete(opts);
POST JSON reformulated
io.post(url, data).
then(result => ...).
catch(res => ...);
Sounds simple, eh?
What we have
XHR: history
The venerable XMLHttpRequest.
Implemented by Microsoft.
For Outlook Web Access.
Shipped in March 1999 in IE5.
As an ActiveX.
Oh, 1999!
March 1999
The Matrix was released.
It blew my mind!
You go, bros sisters!
Let’s POST JSON with XHR I
var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
// set up headers
xhr.setRequestHeader('Content-Type',
'application/json');
xhr.setRequestHeader('Accept-Type',
'application/json');
// continues on the next slide
Let’s POST JSON with XHR II
// optional
xhr.overrideMimeType(
'application/json');
// set up callbacks
xhr.onload = function (e) {};
xhr.onerror = function (e) {};
xhr.ontimeout = function (e) {};
// continues on the next slide
Let’s POST JSON with XHR III
// optional
xhr.onprogress = function (e) {};
xhr.upload.onprogress =
function (e) {};
// finally
xhr.send(JSON.stringify(data));
XHR: summary
Three slides of boilerplate.
Much more with actual code.
Callbacks are not composable.
A lot of repetitive code.
Realistically requires a wrapper.
JSONP: history
Formulated by Bob Ippolito.
Published in December 2005.
Uses existing facilities: <script>
Works in all browsers.
Works cross-origin.
Oh, 2005!
December 2005
First Narnia came out.
SNL’s “Lazy Sunday” on selecting “the
dopest route” to see it:
– I prefer MapQuest!
– That’s a good one too!
– Google Maps is the best!
– True dat! Double true!
Let’s POST JSON with JSONP
We can’t. Limitations:
Only GET verb.
Only query parameters.
Only JSON as a returned value.
Let’s GET JSON with JSONP I
var script =
document.createElement('script');
script.onerror = function (e) {};
window.unique = function (data) {
delete window.unique;
script.parentNode.removeChild(script);
// do something with data
};
// continues on the next slide
Let’s GET JSON with JSONP II
// now we run it
script.src = url +
/* our parameters */ '?a=1' +
'&callback=' +
encodeURIComponent('unique');
document.documentElement.
appendChild(script);
JSONP: summary
Let’s face it: it is a hack.
Callbacks are not composable.
Repetitive code to encode parameters.
Realistically requires a wrapper.
Fetch: history
Started by WHATWG.
Status (April 2017):
Not available in IE11.
Available everywhere else.
Reasonable poly ll is available.
Fetch: details
Uses promises ( nally!).
Model:
fetch(req).then(res => ...)
Allows to handle redirects, CORS.
Fetch: more details
Simpli es Service Workers.
Currently can’t be canceled.
Supports streaming.
De nes numerous classes.
Can be heavy when poly lled.
Fetch: even more details
No cookies are sent by default.
CORS is disabled by default.
Any response from a server is success.
Even 4XX and 5XX ones.
Let’s POST JSON with Fetch I
The example is adapted from Shahal
Talmi’s article.
Angular core contributor.
var opts = {
method: 'POST',
mode: 'cors',
credentials: 'include' // cookies!
};
// continues on the next slide
Let’s POST JSON with Fetch II
// continue filling in opts
opts.headers = {
'Content-Type': 'application/json',
'Accept-Type': 'application/json'
};
opts.body = JSON.stringify(data);
// continues on the next slide
Let’s POST JSON with Fetch III
fetch(url, opts).then(response =>
response.ok ? response.json() :
Promise.reject(response.status)
)
// user's code for then() & catch()
Fetch: summary
Streaming is nice to have, but it is a rare
edge case.
Still a lot of repetitive code.
Due to selected defaults.
Realistically requires a wrapper.
Libraries to the
rescue!
Big gorillas: Angular/React
Both are soft on I/O and data.
Variety of possible options.
Good for us?
Angular 2/4 — don’t
Shahar Talmi (Angular core contributor)
wrote:
Why I won’t be using Fetch API in my
apps
It is a telling title.
Angular 2/4 — do
Shahar suggests:
jQuery’s $.ajax()
Angular’s $http
SuperAgent
Axios — his favorite
Angular’s $http I
Main:
$http(req).toPromise().
then(res => ...)
De nes helpers: get(), head(),
post(), put(), delete(), jsonp(),
patch()
Angular’s $http II
Supports transforming requests and
responses.
Supports GET and JSONP caching.
Supports setting defaults.
Angular’s $http: example
this.http.post(url, data).toPromise().
then(res => {
console.log(res.data);
}).catch(res => {
console.log(res.status);
});
SuperAgent
request
.post('/api/pet')
.send({name: 'Manny'})
.set('Accept', 'application/json')
.end((err, res) =>
alert(err || !res.ok ?
'Oh no! error' :
JSON.parse(res.body))
});
Axios I
POST JSON using the main method:
axios({method: 'post',
url: url, data: data})
// user's then() & catch()
Axios II
POST JSON using a helper:
axios.post(url, data).then(res => {
console.log(res.data);
}).catch(res => {
console.log(res.status);
});
React — do
Redux
Simple: reducers, actions,
middlewares, and stores.
Relay
Implement GraphQL on servers
More modern: Relay Modern
React
So how to POST JSON?
React — really???
Answered on StackOver ow:
Fetch API with poly ll
SuperAgent
Axios
Summary
We can use whatever.
Including our ideal API.
Let’s go back to our micro-library.
heya/io
heya/io I
https://github.com/heya/io
Built using our ideal API.
Supports pluggable services.
Supports pluggable transports.
Thoroughly battle-tested.
heya/io II
Can be used with AMD and globals.
Works with native Promise or any
Promise-like object.
Can be used with heya/async.
Can cancel() I/O.
Supports progress.
POST JSON with heya/io
io.post(url, data).then(result => {
console.log(result);
}).catch(res => {
if (res instanceof io.BadStatus) {
console.log(res.xhr.status);
} else {
console.log(res);
}
});
Advanced I/O
Finally!
Orchestrating I/O
I/O is much more than just a transport.
Caching is a big topic.
App-level cache.
Cache busting.
I/O testing is a must.
Cache issues
In HTTP world cache:
Controlled by a server.
Server cannot recall a response.
Client cannot evict a response.
App-level cache
App frequently knows:
When an object is modi ed.
Dependencies between objects.
We need an app-level cache.
The alternative: no HTTP cache.
Cache issues: servers
Server cache headers are frequently
miscon gured.
Evidence: cache-busting.
/url?bust=123456789
bust uses a random payload, so all
requests are unique.
heya/io is extendable I
The I/O pipeline is well-de ned.
All stages can be extended:
On per-request basis.
On per-app basis.
heya/io is extendable II
Pipeline extensions: services.
XHR replacements: transports.
All extensions should be included
explicitly.
Pay only for what you use.
Extensibility
Flexibility
Orchestration on top of the ideal
API.
heya/io: bust service I
var req = io.get({
url: 'abc',
bust: true
});
// abc?io-bust=1470185125354-507943
heya/io: bust service II
var req = io.get({
url: 'abc',
bust: 'xyz'
});
// abc?xyz=1470185125354-507943
heya/io: bust service III
By default: no bust.
Con gurable:
Bust key.
Bust value generating.
heya.io: cache service I
Storage-based:
Session storage (default).
Local storage (permanent).
Caches GET requests automatically.
To opt out:
cache: false
heya.io: cache service II
Main API (rarely used directly):
io.cache.save('/abc', {a: 1});
io.cache.remove('/abc');
Direct access to the underlying storage
object.
heya/io: mock service I
Simple way to intercept, replace, or
transform an I/O request.
A must for testing!
Trivial redirects.
Rapid prototyping.
heya/io: mock service II
// canned data for exact url
io.mock('/abc', () => 42);
io.get('/abc').then(data => {
console.log(data); // 42
});
heya/io: mock service III
// canned data for url prefix
io.mock('/abc*', () => 42);
io.get('/abc/1').then(data => {
console.log(data); // 42
});
heya/io: mock service IV
// redirect
io.mock('/abc', () => io.get('/xyz'));
io.get('/abc').then(data => {
console.log(data); // from /xyz
});
heya/io: mock service V
// timeout (uses heya/async)
io.mock('/abc', () =>
timeout.resolve(500).then(() => 42));
io.get('/abc').then(data => {
console.log(data); // 42 after 0.5s
});
heya/io: mock service VI
// timeout (uses setTimeout())
io.mock('/abc', () =>
new Promise(resolve => {
setTimeout(function () {
resolve(42);
}, 500);
}));
io.get('/abc').then(data => {
console.log(data); // 42 after 0.5s
});
heya/io: mock service VII
// cascaded calls
io.mock('/abc',
() => io.get('/a').then(
value => io.get('/b', {q: value.x})
).then(
value => io.get('/c', {q: value.y})
)
);
heya/io: mock service VIII
// server error
io.mock('/abc',
() => io.mock.makeXHR({status: 500})
);
heya/io: bundle service I
Traditional I/O
Client Server
HTTPconnections
HTTPconnections
heya/io: bundle service II
Problems with the tradition:
We may exceed number of HTTP
connections.
Potential stalling.
heya/io: bundle service III
Problems with the tradition:
Each payload is small, and
compressed separately.
Poor compression.
heya/io: bundle service IV
Bundle I/O
Client Server
HTTPconnections
HTTPconnections
bundle bundle
heya/io: bundle service V
Bundle’s narrative:
Client collects I/O requests.
Bundles them in one request.
Sends it to a well-known URL.
heya/io: bundle service VI
Bundle’s narrative:
Server acts as a proxy.
Runs all requests in parallel locally.
Sends back collected responses.
heya/io: bundle service VII
Bundle’s narrative:
Client unbundles responses.
Noti es requesters.
heya/io: bundle service VIII
Important points:
Bundling works transparently.
No code modi cations!
Usually GETs are bundled.
To opt out:
bundle: false
heya/io: bundle service IX
Assumes a server handler.
Reference: heya/bundler.
Local server connections are fast and low-
lag.
heya/io: bundle service X
Bundling helps with compression.
Bundling requires just one HTTP
connection.
heya/io: bundle service XI
HTTP/2 alleviates some problems.
Bundle as fast as the slowest request.
In a real app the speed gain was up to
30%.
heya/io: bundle service XII
Bundler can return responses for
unrequested requests.
Similar to HTTP/2 Server Push.
Cache will be populated.
heya/io: bundle service XIII
Behind the scenes:
Client collects requests.
Sends the array as JSON.
Server unpacks.
Runs them in parallel.
heya/io: bundle service XIV
Behind the scenes:
Server collects responses.
Including errors.
Sends the array as JSON back.
Client unpacks, saves to cache.
heya/io: prefetch I
Typical waterfall (served locally):
heya/io: prefetch II
What if we call /api before loading
anything?
Prefetch AKA data forward.
The trick is to do it without libraries.
heya/io: prefetch III
//<html><head><script>
(function () {
var xhr = new XMLHttpRequest();
xhr.onload = function () {
window._r =
JSON.parse(xhr.responseText); };
xhr.open('POST', '/api', true);
xhr.send(null);
}());
//</script></head></html>
heya/io: prefetch IV
Prefetch (served locally):
heya/io: prefetch V
It was 3.69s, now it is 3.22s.
We saved 470ms — whoopee do!
It was under ideal conditions.
Really fast 12 core 64G RAM rig.
How about mobile users?
heya/io: prefetch VI
Typical waterfall (mobile):
heya/io: prefetch VII
Prefetch (mobile):
heya/io: prefetch VII
It was 16.88s, now it is 15.36s.
We saved 1.52s!
We deducted almost all /api.
heya/io: prefetch VIII
bundle service has provisions for
prefetching.
It can be done transparently!
See “Cookbook: bundle” in Wiki of
https://github.com/heya/io
heya/io: summary
Micro-library.
All code < 5k (min/gzip).
No hard dependencies!
Simple ideal API.
Battle-tested and proven.
Works with all libraries.
Summary
Correctly using I/O we can:
Greatly improve performance.
Write clear clean code.
Use ideal API.
Improve perf for free.
That’s all,
folks!

Contenu connexe

Tendances

Beyond JVM - YOW! Sydney 2013
Beyond JVM - YOW! Sydney 2013Beyond JVM - YOW! Sydney 2013
Beyond JVM - YOW! Sydney 2013Charles Nutter
 
Nick Sieger JRuby Concurrency EMRubyConf 2011
Nick Sieger JRuby Concurrency EMRubyConf 2011Nick Sieger JRuby Concurrency EMRubyConf 2011
Nick Sieger JRuby Concurrency EMRubyConf 2011Nick Sieger
 
Connecting the Worlds of Java and Ruby with JRuby
Connecting the Worlds of Java and Ruby with JRubyConnecting the Worlds of Java and Ruby with JRuby
Connecting the Worlds of Java and Ruby with JRubyNick Sieger
 
Fast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible JavaFast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible JavaCharles Nutter
 
Apache CouchDB talk at Ontario GNU Linux Fest
Apache CouchDB talk at Ontario GNU Linux FestApache CouchDB talk at Ontario GNU Linux Fest
Apache CouchDB talk at Ontario GNU Linux FestMyles Braithwaite
 
Logstash-Elasticsearch-Kibana
Logstash-Elasticsearch-KibanaLogstash-Elasticsearch-Kibana
Logstash-Elasticsearch-Kibanadknx01
 
A tale of two proxies
A tale of two proxiesA tale of two proxies
A tale of two proxiesSensePost
 
Inside the JVM - Follow the white rabbit!
Inside the JVM - Follow the white rabbit!Inside the JVM - Follow the white rabbit!
Inside the JVM - Follow the white rabbit!Sylvain Wallez
 
Golang Performance : microbenchmarks, profilers, and a war story
Golang Performance : microbenchmarks, profilers, and a war storyGolang Performance : microbenchmarks, profilers, and a war story
Golang Performance : microbenchmarks, profilers, and a war storyAerospike
 
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011Nick Sieger
 
JVM for Dummies - OSCON 2011
JVM for Dummies - OSCON 2011JVM for Dummies - OSCON 2011
JVM for Dummies - OSCON 2011Charles Nutter
 
JRuby and Invokedynamic - Japan JUG 2015
JRuby and Invokedynamic - Japan JUG 2015JRuby and Invokedynamic - Japan JUG 2015
JRuby and Invokedynamic - Japan JUG 2015Charles Nutter
 
Groovy
GroovyGroovy
Groovyatonse
 
Formatting ForThe Masses
Formatting ForThe MassesFormatting ForThe Masses
Formatting ForThe MassesHolger Schill
 
"Lego Programming" with Lorzy
"Lego Programming" with Lorzy"Lego Programming" with Lorzy
"Lego Programming" with Lorzyclkao
 
Go debugging and troubleshooting tips - from real life lessons at SignalFx
Go debugging and troubleshooting tips - from real life lessons at SignalFxGo debugging and troubleshooting tips - from real life lessons at SignalFx
Go debugging and troubleshooting tips - from real life lessons at SignalFxSignalFx
 

Tendances (20)

Beyond JVM - YOW! Sydney 2013
Beyond JVM - YOW! Sydney 2013Beyond JVM - YOW! Sydney 2013
Beyond JVM - YOW! Sydney 2013
 
Web::Scraper
Web::ScraperWeb::Scraper
Web::Scraper
 
Nick Sieger JRuby Concurrency EMRubyConf 2011
Nick Sieger JRuby Concurrency EMRubyConf 2011Nick Sieger JRuby Concurrency EMRubyConf 2011
Nick Sieger JRuby Concurrency EMRubyConf 2011
 
ORMs in Golang
ORMs in GolangORMs in Golang
ORMs in Golang
 
Connecting the Worlds of Java and Ruby with JRuby
Connecting the Worlds of Java and Ruby with JRubyConnecting the Worlds of Java and Ruby with JRuby
Connecting the Worlds of Java and Ruby with JRuby
 
Fast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible JavaFast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible Java
 
Apache CouchDB talk at Ontario GNU Linux Fest
Apache CouchDB talk at Ontario GNU Linux FestApache CouchDB talk at Ontario GNU Linux Fest
Apache CouchDB talk at Ontario GNU Linux Fest
 
Logstash-Elasticsearch-Kibana
Logstash-Elasticsearch-KibanaLogstash-Elasticsearch-Kibana
Logstash-Elasticsearch-Kibana
 
A tale of two proxies
A tale of two proxiesA tale of two proxies
A tale of two proxies
 
Inside the JVM - Follow the white rabbit!
Inside the JVM - Follow the white rabbit!Inside the JVM - Follow the white rabbit!
Inside the JVM - Follow the white rabbit!
 
Golang Performance : microbenchmarks, profilers, and a war story
Golang Performance : microbenchmarks, profilers, and a war storyGolang Performance : microbenchmarks, profilers, and a war story
Golang Performance : microbenchmarks, profilers, and a war story
 
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
 
JVM for Dummies - OSCON 2011
JVM for Dummies - OSCON 2011JVM for Dummies - OSCON 2011
JVM for Dummies - OSCON 2011
 
Using Logstash, elasticsearch & kibana
Using Logstash, elasticsearch & kibanaUsing Logstash, elasticsearch & kibana
Using Logstash, elasticsearch & kibana
 
Python Web Interaction
Python Web InteractionPython Web Interaction
Python Web Interaction
 
JRuby and Invokedynamic - Japan JUG 2015
JRuby and Invokedynamic - Japan JUG 2015JRuby and Invokedynamic - Japan JUG 2015
JRuby and Invokedynamic - Japan JUG 2015
 
Groovy
GroovyGroovy
Groovy
 
Formatting ForThe Masses
Formatting ForThe MassesFormatting ForThe Masses
Formatting ForThe Masses
 
"Lego Programming" with Lorzy
"Lego Programming" with Lorzy"Lego Programming" with Lorzy
"Lego Programming" with Lorzy
 
Go debugging and troubleshooting tips - from real life lessons at SignalFx
Go debugging and troubleshooting tips - from real life lessons at SignalFxGo debugging and troubleshooting tips - from real life lessons at SignalFx
Go debugging and troubleshooting tips - from real life lessons at SignalFx
 

Similaire à Advanced I/O in browser

JSON Fuzzing: New approach to old problems
JSON Fuzzing: New  approach to old problemsJSON Fuzzing: New  approach to old problems
JSON Fuzzing: New approach to old problemstitanlambda
 
Streams of information - Chicago crystal language monthly meetup
Streams of information - Chicago crystal language monthly meetupStreams of information - Chicago crystal language monthly meetup
Streams of information - Chicago crystal language monthly meetupBrian Cardiff
 
Introduction to node.js
Introduction to node.jsIntroduction to node.js
Introduction to node.jsAdrien Guéret
 
Web program-peformance-optimization
Web program-peformance-optimizationWeb program-peformance-optimization
Web program-peformance-optimizationxiaojueqq12345
 
Node.js: CAMTA Presentation
Node.js: CAMTA PresentationNode.js: CAMTA Presentation
Node.js: CAMTA PresentationRob Tweed
 
IPTC News in JSON Spring 2013
IPTC News in JSON Spring 2013IPTC News in JSON Spring 2013
IPTC News in JSON Spring 2013Stuart Myles
 
iOS Swift application architecture
iOS Swift application architectureiOS Swift application architecture
iOS Swift application architectureRomain Rochegude
 
Jsonsaga 100605143125-phpapp02
Jsonsaga 100605143125-phpapp02Jsonsaga 100605143125-phpapp02
Jsonsaga 100605143125-phpapp02Ramamohan Chokkam
 
Introduction to Vert.x
Introduction to Vert.xIntroduction to Vert.x
Introduction to Vert.xYiguang Hu
 
SXSW 2012 JavaScript MythBusters
SXSW 2012 JavaScript MythBustersSXSW 2012 JavaScript MythBusters
SXSW 2012 JavaScript MythBustersElena-Oana Tabaranu
 
Implementing Ajax In ColdFusion 7
Implementing Ajax In ColdFusion 7Implementing Ajax In ColdFusion 7
Implementing Ajax In ColdFusion 7Pranav Prakash
 
Cross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App EngineCross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App EngineAndy McKay
 
sbt, history of JSON libraries, microservices, and schema evolution (Tokyo ver)
sbt, history of JSON libraries, microservices, and schema evolution (Tokyo ver)sbt, history of JSON libraries, microservices, and schema evolution (Tokyo ver)
sbt, history of JSON libraries, microservices, and schema evolution (Tokyo ver)Eugene Yokota
 
jQuery with javascript training by Technnovation Labs
jQuery with javascript training by Technnovation LabsjQuery with javascript training by Technnovation Labs
jQuery with javascript training by Technnovation LabsPrasad Shende
 
Asynchronous I/O in NodeJS - new standard or challenges?
Asynchronous I/O in NodeJS - new standard or challenges?Asynchronous I/O in NodeJS - new standard or challenges?
Asynchronous I/O in NodeJS - new standard or challenges?Dinh Pham
 

Similaire à Advanced I/O in browser (20)

JSON Fuzzing: New approach to old problems
JSON Fuzzing: New  approach to old problemsJSON Fuzzing: New  approach to old problems
JSON Fuzzing: New approach to old problems
 
JS everywhere 2011
JS everywhere 2011JS everywhere 2011
JS everywhere 2011
 
Streams of information - Chicago crystal language monthly meetup
Streams of information - Chicago crystal language monthly meetupStreams of information - Chicago crystal language monthly meetup
Streams of information - Chicago crystal language monthly meetup
 
NodeJS
NodeJSNodeJS
NodeJS
 
Introduction to node.js
Introduction to node.jsIntroduction to node.js
Introduction to node.js
 
Web program-peformance-optimization
Web program-peformance-optimizationWeb program-peformance-optimization
Web program-peformance-optimization
 
AJAX
AJAXAJAX
AJAX
 
Node.js: CAMTA Presentation
Node.js: CAMTA PresentationNode.js: CAMTA Presentation
Node.js: CAMTA Presentation
 
IPTC News in JSON Spring 2013
IPTC News in JSON Spring 2013IPTC News in JSON Spring 2013
IPTC News in JSON Spring 2013
 
Best Of Jdk 7
Best Of Jdk 7Best Of Jdk 7
Best Of Jdk 7
 
iOS Swift application architecture
iOS Swift application architectureiOS Swift application architecture
iOS Swift application architecture
 
Jsonsaga 100605143125-phpapp02
Jsonsaga 100605143125-phpapp02Jsonsaga 100605143125-phpapp02
Jsonsaga 100605143125-phpapp02
 
Introduction to Vert.x
Introduction to Vert.xIntroduction to Vert.x
Introduction to Vert.x
 
huhu
huhuhuhu
huhu
 
SXSW 2012 JavaScript MythBusters
SXSW 2012 JavaScript MythBustersSXSW 2012 JavaScript MythBusters
SXSW 2012 JavaScript MythBusters
 
Implementing Ajax In ColdFusion 7
Implementing Ajax In ColdFusion 7Implementing Ajax In ColdFusion 7
Implementing Ajax In ColdFusion 7
 
Cross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App EngineCross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App Engine
 
sbt, history of JSON libraries, microservices, and schema evolution (Tokyo ver)
sbt, history of JSON libraries, microservices, and schema evolution (Tokyo ver)sbt, history of JSON libraries, microservices, and schema evolution (Tokyo ver)
sbt, history of JSON libraries, microservices, and schema evolution (Tokyo ver)
 
jQuery with javascript training by Technnovation Labs
jQuery with javascript training by Technnovation LabsjQuery with javascript training by Technnovation Labs
jQuery with javascript training by Technnovation Labs
 
Asynchronous I/O in NodeJS - new standard or challenges?
Asynchronous I/O in NodeJS - new standard or challenges?Asynchronous I/O in NodeJS - new standard or challenges?
Asynchronous I/O in NodeJS - new standard or challenges?
 

Plus de Eugene Lazutkin

Functional practices in JavaScript
Functional practices in JavaScriptFunctional practices in JavaScript
Functional practices in JavaScriptEugene Lazutkin
 
Express: the web server for node.js
Express: the web server for node.jsExpress: the web server for node.js
Express: the web server for node.jsEugene Lazutkin
 
Practical pairing of generative programming with functional programming.
Practical pairing of generative programming with functional programming.Practical pairing of generative programming with functional programming.
Practical pairing of generative programming with functional programming.Eugene Lazutkin
 
Optimization of modern web applications
Optimization of modern web applicationsOptimization of modern web applications
Optimization of modern web applicationsEugene Lazutkin
 
SSJS, NoSQL, GAE and AppengineJS
SSJS, NoSQL, GAE and AppengineJSSSJS, NoSQL, GAE and AppengineJS
SSJS, NoSQL, GAE and AppengineJSEugene Lazutkin
 
Dojo for programmers (TXJS 2010)
Dojo for programmers (TXJS 2010)Dojo for programmers (TXJS 2010)
Dojo for programmers (TXJS 2010)Eugene Lazutkin
 
Exciting JavaScript - Part II
Exciting JavaScript - Part IIExciting JavaScript - Part II
Exciting JavaScript - Part IIEugene Lazutkin
 
Exciting JavaScript - Part I
Exciting JavaScript - Part IExciting JavaScript - Part I
Exciting JavaScript - Part IEugene Lazutkin
 
Dojo GFX workshop slides
Dojo GFX workshop slidesDojo GFX workshop slides
Dojo GFX workshop slidesEugene Lazutkin
 
Dojo GFX: SVG in the real world
Dojo GFX: SVG in the real worldDojo GFX: SVG in the real world
Dojo GFX: SVG in the real worldEugene Lazutkin
 
DojoX GFX Session Eugene Lazutkin SVG Open 2007
DojoX GFX Session Eugene Lazutkin SVG Open 2007DojoX GFX Session Eugene Lazutkin SVG Open 2007
DojoX GFX Session Eugene Lazutkin SVG Open 2007Eugene Lazutkin
 
DojoX GFX Keynote Eugene Lazutkin SVG Open 2007
DojoX GFX Keynote Eugene Lazutkin SVG Open 2007DojoX GFX Keynote Eugene Lazutkin SVG Open 2007
DojoX GFX Keynote Eugene Lazutkin SVG Open 2007Eugene Lazutkin
 

Plus de Eugene Lazutkin (20)

Service workers
Service workersService workers
Service workers
 
Streams
StreamsStreams
Streams
 
Functional practices in JavaScript
Functional practices in JavaScriptFunctional practices in JavaScript
Functional practices in JavaScript
 
Express: the web server for node.js
Express: the web server for node.jsExpress: the web server for node.js
Express: the web server for node.js
 
TXJS 2013 in 10 minutes
TXJS 2013 in 10 minutesTXJS 2013 in 10 minutes
TXJS 2013 in 10 minutes
 
Practical pairing of generative programming with functional programming.
Practical pairing of generative programming with functional programming.Practical pairing of generative programming with functional programming.
Practical pairing of generative programming with functional programming.
 
Optimization of modern web applications
Optimization of modern web applicationsOptimization of modern web applications
Optimization of modern web applications
 
OOP in JS
OOP in JSOOP in JS
OOP in JS
 
Pulsar
PulsarPulsar
Pulsar
 
SSJS, NoSQL, GAE and AppengineJS
SSJS, NoSQL, GAE and AppengineJSSSJS, NoSQL, GAE and AppengineJS
SSJS, NoSQL, GAE and AppengineJS
 
Dojo for programmers (TXJS 2010)
Dojo for programmers (TXJS 2010)Dojo for programmers (TXJS 2010)
Dojo for programmers (TXJS 2010)
 
Exciting JavaScript - Part II
Exciting JavaScript - Part IIExciting JavaScript - Part II
Exciting JavaScript - Part II
 
RAD CRUD
RAD CRUDRAD CRUD
RAD CRUD
 
Exciting JavaScript - Part I
Exciting JavaScript - Part IExciting JavaScript - Part I
Exciting JavaScript - Part I
 
CRUD with Dojo
CRUD with DojoCRUD with Dojo
CRUD with Dojo
 
Dojo GFX workshop slides
Dojo GFX workshop slidesDojo GFX workshop slides
Dojo GFX workshop slides
 
Dojo GFX: SVG in the real world
Dojo GFX: SVG in the real worldDojo GFX: SVG in the real world
Dojo GFX: SVG in the real world
 
Dojo (QCon 2007 Slides)
Dojo (QCon 2007 Slides)Dojo (QCon 2007 Slides)
Dojo (QCon 2007 Slides)
 
DojoX GFX Session Eugene Lazutkin SVG Open 2007
DojoX GFX Session Eugene Lazutkin SVG Open 2007DojoX GFX Session Eugene Lazutkin SVG Open 2007
DojoX GFX Session Eugene Lazutkin SVG Open 2007
 
DojoX GFX Keynote Eugene Lazutkin SVG Open 2007
DojoX GFX Keynote Eugene Lazutkin SVG Open 2007DojoX GFX Keynote Eugene Lazutkin SVG Open 2007
DojoX GFX Keynote Eugene Lazutkin SVG Open 2007
 

Dernier

2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 

Dernier (20)

2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 

Advanced I/O in browser

  • 1. Advanced I/O in browser Eugene Lazutkin, 5/2/2017, ClubAjax, Dallas, TX @uhop, www.lazutkin.com
  • 2. Outline Prototype an I/O library. What we have, and what is wrong with it. Libraries! What do Angular and React do? Back to the board! Advanced I/O
  • 3. Browser Now provides all low-level stuff. We can (without jQuery!): Search by selector. Calculate geometry. Manipulate CSS classes. Much more!
  • 4. How about I/O? Stone age. We still need to use libraries. Let’s design an ideal solution. Then compare it with what we have.
  • 6. HTTP Simple text format. The same is used by HTTPS. Covered by standards. Uses verbs and status codes. Consists of headers and body.
  • 7. HTTP request POST /api HTTP/1.1 Host: localhost:8000 Connection: keep-alive User-Agent: ...user agent string... Content-Type: application/json Accept-Encoding: gzip, deflate Cookie: io=JSwSxqG0tIMQ_ZtZAABl ...body, if needed...
  • 8. HTTP response HTTP/1.1 200 OK Content-Type: application/json Content-Length: 18193 Date: Sun, 30 Apr 2017 23:52:36 GMT ...body, if needed...
  • 9. Design decisions I Return Promise. Helps with composability. A way from the callback hell. Pack all request parameters together. Use raw {} for simplicity. We can manipulate it.
  • 10. Design decisions II Be smart about response Users want to deal in terms of data: Send data Receive data In most cases a response object is not needed.
  • 11. Design decisions III Be smart about response Sometimes we need a response: To read status and headers. Cater for most common cases: JSON in/out should be simple. The rest should be possible.
  • 12. Design decisions IV We interpret status code. 4XX and 5XX are bad statuses. 204 is good, but no response. ⇒ undefined.
  • 13. Design decisions V We interpret MIME. If you don’t set: Content-Type Accept-Type ⇒ application/json
  • 14. Design decisions VI Recognize special data: FormData — forms. Document — XML. ArrayBuffer, Blob.
  • 15. Design decisions VII Form query: Bad: url: '/abc/?name=' + name + '&age=' + age Good: url: '/abc', query: {name: name, age: age}
  • 16. XKCD: Exploits of a Mom https://xkcd.com/327/ Don’t be a Bobby Tables!
  • 17. Design decisions VIII Different types for different errors. Use instanceof to make a choice. Errors: wrong request, timeout, bad status.
  • 18. Result io({ url: url, method: 'POST', headers: { 'X-Custom-Header': 'abc' }, data: data // JSON }) // then() and catch()
  • 19. Result: POST JSON example io(req).then(result => { console.log(result.name); }).catch(res => { if(res instanceof io.FailedIO) {} if(res instanceof io.TimedOut) {} if(res instanceof io.BadStatus) { console.log(res.xhr.status); } });
  • 20. How we interpret result? We know Content-Type. application/json ⇒ JSON. application/xml ⇒ XML. MIME types are covered by RFCs. We can map them to whatever. Or return a string or a buffer.
  • 21. Design: helpers I We can provide helpers for verbs: io.get (url, queryData); io.head (url, queryData); io.post (url, data); io.put (url, data); io.patch (url, data); io.delete (url, data);
  • 22. Design: helpers II url is a string, or an object like for io(). queryData and data are optional. A helper overrides a verb.
  • 23. Design: helpers III // url as an object? for REST: var opts = {url: url, headers: headers}; io.get(opts); io.put(opts, data); io.patch(opts, data); io.delete(opts);
  • 24. POST JSON reformulated io.post(url, data). then(result => ...). catch(res => ...); Sounds simple, eh?
  • 26. XHR: history The venerable XMLHttpRequest. Implemented by Microsoft. For Outlook Web Access. Shipped in March 1999 in IE5. As an ActiveX.
  • 28. March 1999 The Matrix was released. It blew my mind! You go, bros sisters!
  • 29. Let’s POST JSON with XHR I var xhr = new XMLHttpRequest(); xhr.open('POST', url, true); // set up headers xhr.setRequestHeader('Content-Type', 'application/json'); xhr.setRequestHeader('Accept-Type', 'application/json'); // continues on the next slide
  • 30. Let’s POST JSON with XHR II // optional xhr.overrideMimeType( 'application/json'); // set up callbacks xhr.onload = function (e) {}; xhr.onerror = function (e) {}; xhr.ontimeout = function (e) {}; // continues on the next slide
  • 31. Let’s POST JSON with XHR III // optional xhr.onprogress = function (e) {}; xhr.upload.onprogress = function (e) {}; // finally xhr.send(JSON.stringify(data));
  • 32. XHR: summary Three slides of boilerplate. Much more with actual code. Callbacks are not composable. A lot of repetitive code. Realistically requires a wrapper.
  • 33. JSONP: history Formulated by Bob Ippolito. Published in December 2005. Uses existing facilities: <script> Works in all browsers. Works cross-origin.
  • 35. December 2005 First Narnia came out. SNL’s “Lazy Sunday” on selecting “the dopest route” to see it: – I prefer MapQuest! – That’s a good one too! – Google Maps is the best! – True dat! Double true!
  • 36. Let’s POST JSON with JSONP We can’t. Limitations: Only GET verb. Only query parameters. Only JSON as a returned value.
  • 37. Let’s GET JSON with JSONP I var script = document.createElement('script'); script.onerror = function (e) {}; window.unique = function (data) { delete window.unique; script.parentNode.removeChild(script); // do something with data }; // continues on the next slide
  • 38. Let’s GET JSON with JSONP II // now we run it script.src = url + /* our parameters */ '?a=1' + '&callback=' + encodeURIComponent('unique'); document.documentElement. appendChild(script);
  • 39. JSONP: summary Let’s face it: it is a hack. Callbacks are not composable. Repetitive code to encode parameters. Realistically requires a wrapper.
  • 40. Fetch: history Started by WHATWG. Status (April 2017): Not available in IE11. Available everywhere else. Reasonable poly ll is available.
  • 41. Fetch: details Uses promises ( nally!). Model: fetch(req).then(res => ...) Allows to handle redirects, CORS.
  • 42. Fetch: more details Simpli es Service Workers. Currently can’t be canceled. Supports streaming. De nes numerous classes. Can be heavy when poly lled.
  • 43. Fetch: even more details No cookies are sent by default. CORS is disabled by default. Any response from a server is success. Even 4XX and 5XX ones.
  • 44. Let’s POST JSON with Fetch I The example is adapted from Shahal Talmi’s article. Angular core contributor. var opts = { method: 'POST', mode: 'cors', credentials: 'include' // cookies! }; // continues on the next slide
  • 45. Let’s POST JSON with Fetch II // continue filling in opts opts.headers = { 'Content-Type': 'application/json', 'Accept-Type': 'application/json' }; opts.body = JSON.stringify(data); // continues on the next slide
  • 46. Let’s POST JSON with Fetch III fetch(url, opts).then(response => response.ok ? response.json() : Promise.reject(response.status) ) // user's code for then() & catch()
  • 47. Fetch: summary Streaming is nice to have, but it is a rare edge case. Still a lot of repetitive code. Due to selected defaults. Realistically requires a wrapper.
  • 49. Big gorillas: Angular/React Both are soft on I/O and data. Variety of possible options. Good for us?
  • 50. Angular 2/4 — don’t Shahar Talmi (Angular core contributor) wrote: Why I won’t be using Fetch API in my apps It is a telling title.
  • 51. Angular 2/4 — do Shahar suggests: jQuery’s $.ajax() Angular’s $http SuperAgent Axios — his favorite
  • 52. Angular’s $http I Main: $http(req).toPromise(). then(res => ...) De nes helpers: get(), head(), post(), put(), delete(), jsonp(), patch()
  • 53. Angular’s $http II Supports transforming requests and responses. Supports GET and JSONP caching. Supports setting defaults.
  • 54. Angular’s $http: example this.http.post(url, data).toPromise(). then(res => { console.log(res.data); }).catch(res => { console.log(res.status); });
  • 55. SuperAgent request .post('/api/pet') .send({name: 'Manny'}) .set('Accept', 'application/json') .end((err, res) => alert(err || !res.ok ? 'Oh no! error' : JSON.parse(res.body)) });
  • 56. Axios I POST JSON using the main method: axios({method: 'post', url: url, data: data}) // user's then() & catch()
  • 57. Axios II POST JSON using a helper: axios.post(url, data).then(res => { console.log(res.data); }).catch(res => { console.log(res.status); });
  • 58. React — do Redux Simple: reducers, actions, middlewares, and stores. Relay Implement GraphQL on servers More modern: Relay Modern
  • 59. React So how to POST JSON?
  • 60. React — really??? Answered on StackOver ow: Fetch API with poly ll SuperAgent Axios
  • 61. Summary We can use whatever. Including our ideal API. Let’s go back to our micro-library.
  • 63. heya/io I https://github.com/heya/io Built using our ideal API. Supports pluggable services. Supports pluggable transports. Thoroughly battle-tested.
  • 64. heya/io II Can be used with AMD and globals. Works with native Promise or any Promise-like object. Can be used with heya/async. Can cancel() I/O. Supports progress.
  • 65. POST JSON with heya/io io.post(url, data).then(result => { console.log(result); }).catch(res => { if (res instanceof io.BadStatus) { console.log(res.xhr.status); } else { console.log(res); } });
  • 67. Orchestrating I/O I/O is much more than just a transport. Caching is a big topic. App-level cache. Cache busting. I/O testing is a must.
  • 68. Cache issues In HTTP world cache: Controlled by a server. Server cannot recall a response. Client cannot evict a response.
  • 69. App-level cache App frequently knows: When an object is modi ed. Dependencies between objects. We need an app-level cache. The alternative: no HTTP cache.
  • 70. Cache issues: servers Server cache headers are frequently miscon gured. Evidence: cache-busting. /url?bust=123456789 bust uses a random payload, so all requests are unique.
  • 71. heya/io is extendable I The I/O pipeline is well-de ned. All stages can be extended: On per-request basis. On per-app basis.
  • 72. heya/io is extendable II Pipeline extensions: services. XHR replacements: transports. All extensions should be included explicitly. Pay only for what you use.
  • 74. heya/io: bust service I var req = io.get({ url: 'abc', bust: true }); // abc?io-bust=1470185125354-507943
  • 75. heya/io: bust service II var req = io.get({ url: 'abc', bust: 'xyz' }); // abc?xyz=1470185125354-507943
  • 76. heya/io: bust service III By default: no bust. Con gurable: Bust key. Bust value generating.
  • 77. heya.io: cache service I Storage-based: Session storage (default). Local storage (permanent). Caches GET requests automatically. To opt out: cache: false
  • 78. heya.io: cache service II Main API (rarely used directly): io.cache.save('/abc', {a: 1}); io.cache.remove('/abc'); Direct access to the underlying storage object.
  • 79. heya/io: mock service I Simple way to intercept, replace, or transform an I/O request. A must for testing! Trivial redirects. Rapid prototyping.
  • 80. heya/io: mock service II // canned data for exact url io.mock('/abc', () => 42); io.get('/abc').then(data => { console.log(data); // 42 });
  • 81. heya/io: mock service III // canned data for url prefix io.mock('/abc*', () => 42); io.get('/abc/1').then(data => { console.log(data); // 42 });
  • 82. heya/io: mock service IV // redirect io.mock('/abc', () => io.get('/xyz')); io.get('/abc').then(data => { console.log(data); // from /xyz });
  • 83. heya/io: mock service V // timeout (uses heya/async) io.mock('/abc', () => timeout.resolve(500).then(() => 42)); io.get('/abc').then(data => { console.log(data); // 42 after 0.5s });
  • 84. heya/io: mock service VI // timeout (uses setTimeout()) io.mock('/abc', () => new Promise(resolve => { setTimeout(function () { resolve(42); }, 500); })); io.get('/abc').then(data => { console.log(data); // 42 after 0.5s });
  • 85. heya/io: mock service VII // cascaded calls io.mock('/abc', () => io.get('/a').then( value => io.get('/b', {q: value.x}) ).then( value => io.get('/c', {q: value.y}) ) );
  • 86. heya/io: mock service VIII // server error io.mock('/abc', () => io.mock.makeXHR({status: 500}) );
  • 87. heya/io: bundle service I Traditional I/O Client Server HTTPconnections HTTPconnections
  • 88. heya/io: bundle service II Problems with the tradition: We may exceed number of HTTP connections. Potential stalling.
  • 89. heya/io: bundle service III Problems with the tradition: Each payload is small, and compressed separately. Poor compression.
  • 90. heya/io: bundle service IV Bundle I/O Client Server HTTPconnections HTTPconnections bundle bundle
  • 91. heya/io: bundle service V Bundle’s narrative: Client collects I/O requests. Bundles them in one request. Sends it to a well-known URL.
  • 92. heya/io: bundle service VI Bundle’s narrative: Server acts as a proxy. Runs all requests in parallel locally. Sends back collected responses.
  • 93. heya/io: bundle service VII Bundle’s narrative: Client unbundles responses. Noti es requesters.
  • 94. heya/io: bundle service VIII Important points: Bundling works transparently. No code modi cations! Usually GETs are bundled. To opt out: bundle: false
  • 95. heya/io: bundle service IX Assumes a server handler. Reference: heya/bundler. Local server connections are fast and low- lag.
  • 96. heya/io: bundle service X Bundling helps with compression. Bundling requires just one HTTP connection.
  • 97. heya/io: bundle service XI HTTP/2 alleviates some problems. Bundle as fast as the slowest request. In a real app the speed gain was up to 30%.
  • 98. heya/io: bundle service XII Bundler can return responses for unrequested requests. Similar to HTTP/2 Server Push. Cache will be populated.
  • 99. heya/io: bundle service XIII Behind the scenes: Client collects requests. Sends the array as JSON. Server unpacks. Runs them in parallel.
  • 100. heya/io: bundle service XIV Behind the scenes: Server collects responses. Including errors. Sends the array as JSON back. Client unpacks, saves to cache.
  • 101. heya/io: prefetch I Typical waterfall (served locally):
  • 102. heya/io: prefetch II What if we call /api before loading anything? Prefetch AKA data forward. The trick is to do it without libraries.
  • 103. heya/io: prefetch III //<html><head><script> (function () { var xhr = new XMLHttpRequest(); xhr.onload = function () { window._r = JSON.parse(xhr.responseText); }; xhr.open('POST', '/api', true); xhr.send(null); }()); //</script></head></html>
  • 104. heya/io: prefetch IV Prefetch (served locally):
  • 105. heya/io: prefetch V It was 3.69s, now it is 3.22s. We saved 470ms — whoopee do! It was under ideal conditions. Really fast 12 core 64G RAM rig. How about mobile users?
  • 106. heya/io: prefetch VI Typical waterfall (mobile):
  • 108. heya/io: prefetch VII It was 16.88s, now it is 15.36s. We saved 1.52s! We deducted almost all /api.
  • 109. heya/io: prefetch VIII bundle service has provisions for prefetching. It can be done transparently! See “Cookbook: bundle” in Wiki of https://github.com/heya/io
  • 110. heya/io: summary Micro-library. All code < 5k (min/gzip). No hard dependencies! Simple ideal API. Battle-tested and proven. Works with all libraries.
  • 111. Summary Correctly using I/O we can: Greatly improve performance. Write clear clean code. Use ideal API. Improve perf for free.