By João Silva for the CERN Spring Campus 2014
University of Oviedo, Gijón, Spain
{
"name": "João Silva",
"country": "Portugal",
"employer": "CERN",
"title": "Software Engineer",
"technologies": [
"Java",
"JavaScript",
"Groovy",
"Grails",
"Activiti Workflow"
],
"email": "joao.p.silva@cern.ch"
}
→
Netscape Navigator
The Dawn of JavaScript, how it all began. How many of you recognize this logo?
It's the logo of Netscape Navigator, one of the world's first web browsers, and the dominant one in terms of usage share in the 1990s. But, most importantly, it was the browser for which JavaScript was originally developed.Glue language
Originally, it was called Mocha, then rebranded LiveScript, to match the LiveWire server-side product of Netscape, and later, to JavaScript, mainly for marketing reasons, as Java was very popular at the time, and Netscape wanted to capitalize that popularity.
But it has very little to do with Java. In fact, it was inspired by other two languages: Scheme and Self. From Scheme, a functional language based on Lisp, it took first-class functions and closures. A first-class function is essentially the ability of a language to pass a function as an argument to another function, to return a function from a function, or to assign a function to a variable. In other words, you treat functions in the same way you treat other types, such as integers or Strings.
From Self, it took prototypes, a style of OOP in which behaviour reuse (inheritance) is performed via a process of cloning existing objects. There are no explicit classes, like in Java. With prototypes, objects inherit from existing objects, you can't get more object-oriented with this.It was originally designed as a glue language, to provide form validations and adding interactivitiy to web pages.
And to understand why, you have to think about the time when JavaScript was invented. In 1995, when use of telephone modems was widespread, a round-trip to the server was a very expensive operation. Suppose you were filling an online form, and then you click the submit button. It could take 30s to get back an answer from the server. Now imagine how annoying it would be if after waiting, you received an error from the server, telling you that you forgot to fill in the e-mail. Very annoying! So Netscape invented JavaScript, which allowed you to perform validations on the client (the browser), before the form was submitted to the server.Internet Explorer vs Netscape Navigator
standardize the syntax and semantics of a general purpose, cross-platform, vendor-neutral scripting language
Google's open source JavaScript engine
It uses a Just-in-Time compiler to compile JavaScript source code directly into machine code when it is first executed. There is no intermediate bytecode, no interpreter.
Then it has a profiler which identifies hot functions, and recompiles them with another compiler, which produces even more optimized code
It's blazingly fast
It has a module system, which allows you to encapsulate your code, and split large projects into multiple files
We have test frameworks, which allows you to easily unit test your code
Code quality tools, which help you detect errors and potential problems in your code, ans also to enforce code conventions (e.g. duplicate variable names, not inserting a semicolon at the end of each statement
Package manager, similar to Maven for Java
Task runner, similar to Ant for Java, which allows you to define lists of tasks to be executed sequentially (e.g. first you run tests, then you minify your files, then you deploy them
Monoglot programming
Server-side JavaScript
Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.
The basic thesis of node.js is that I/O needs to be done differently.
Source: Ryan Dahl's JSConf node.js presentation
var results = db.query('select * from bigtable'); // Blocking
// Process results
fs.writeFile('/var/log/', 'bla');
var response = JSON.stringify(results);
Most web applications are I/O bound, not CPU bound
Node.js was designed to exploit this imbalance
The slim dark green bars represent the time your app devotes to processing and the grey bars the time spent waiting for I/O to complete.
As you can see, the vast majority of time is spent on I/O, waiting. That's because most web applications are I/O bound, not CPU bound! Node.js was designed to exploit this imbalance because better software can multitask.
It relies on the premise that time spent waiting for I/O far outweighs the time spent executing application logic. If your application is more CPU-intensive (calculating Pi up to a trillion digits), then Node.js is not the right platform. You'll block the event loop.
var results = db.query('select * from bigtable');
// Process results
db.query('select * from bigtable', function(results) {
// Process results
});
JavaScript fits perfectly the event loop model with first-class functions and closures
var fs = require('fs');
fs.readFile('hello.txt', function(err, data) {
if (err) throw err;
console.log(data);
});
var net = require('net');
var server = net.createServer(function (socket) {
socket.write('Welcome to the echo server\r\n');
socket.pipe(socket);
});
server.listen(1337);
var http = require('http');
var server = http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'text/html'});
response.end('<h1>Hello World</h1>');
});
server.listen(1337);
console.log('Server running at http://127.0.0.1:1337/');
web application framework for node.js
Express is a minimal and flexible node.js web application framework, providing a robust set of features for building single and multi-page, and hybrid web applications.
var http = require("http");
var fs = require("fs");
http.createServer(function(req, res) {
// Homepage
if (req.url == "/") {
res.writeHead(200, { "Content-Type": "text/html" });
res.end("Welcome to the homepage!");
}
// About page
else if (req.url == "/about") {
res.writeHead(200, { "Content-Type": "text/html" });
fs.readFile(__dirname + "/about.html", function (err, data) {
res.end(data);
});
}
// 404'd!
else {
res.writeHead(404, { "Content-Type": "text/plain" });
res.end("404 error! File not found.");
}
}).listen(1337);
var express = require("express");
var app = express();
app.get("/", function(request, response) {
response.send("<h1>Welcome to the home page!</h1>");
});
app.get("/about", function(request, response) {
response.render("about.html");
});
app.all("*", function(request, response) {
response.send(404, "404 error! File not found.");
});
app.listen(1337);
Map different requests to specific handlers
var express = require("express");
var app = express();
app.post("/action/:id?", function(request, response) {
var id = request.params.id;
response.send(id ? "hello " + id : "hello");
});
app.get("/json", function(request, response) {
response.send({ foo: "bar" });
});
app.all("*", function(request, response) {
response.send(404, "404 error! File not found.");
});
app.listen(1337);
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser());
app.get('/', function(req, res) {
res.send('<form method="post" action="/">' +
'Name: <input type="text" name="username" />' +
'<input type="submit" />' +
'</form>');
});
app.post('/', function(req, res) {
// Always sanitize your data to prevent XSS, remember Derek's presentation!
res.send('¡Bienvenido!, ' + sanitize(req.body.username));
});
app.listen(1337);
doctype html
html(lang="en")
head
title =pageTitle
body
h1 Welcome to the #{pageTitle}!
p Jade is a cool, high-performance templating engine for Node.js.
var express = require('express');
var app = express();
app.get('/', function(req, res) {
res.render('index.jade', { pageTitle: 'CERN Spring Campus 2014' });
});
html
body
h1 Profound Quotes
block content
extends layout
block content
p The cave that you fear to enter holds the treasure you seek.
var express = require('express');
var app = express();
app.set('view engine', 'jade');
app.get('/', function(req, res) {
res.render('quotes');
});
<!DOCTYPE html>
<html>
<body>
<h1>Profound Quotes</h1>
<p>The cave that you fear to enter holds the treasure you seek.</p>
</body>
</html>
Middle layer between Express and the network
var express = require('express');
var app = express();
// A middleware is a function (request handler) with three arguments
var ensureAuthenticated = function(req, res, next) {
if (req.isAuthenticated()) {
var username = req.username;
req.user = User.findByUsername(username);
return next();
}
return res.redirect("/login");
};
app.use(ensureAuthenticated);
app.get('/', function(req, res) {
res.send('Welcome ' + req.user);
});
app.configure(function () {
app.set('views', __dirname + '/views');
app.use(staticProvider(__dirname + '/public');
app.use(bodyParser());
app.use(csrf());
app.use(session());
});
app.configure('development', function () {
app.use(errorHandler({
dumpExceptions: true,
showStack: true
});
app.disable('emails');
});
app.configure('production', function () {
app.use(errorHandler());
app.enable('emails');
});
open-source document database
MongoDB (from "humongous") is an open-source document database, and the leading NoSQL database.
Next Generation Databases mostly addressing some of the points: being non-relational, distributed, open-source and horizontally scalable.
Source: http://martinfowler.com/bliki/AggregateOrientedDatabase.html
Data stored as whole documents
Source: http://docs.mongodb.org/manual/core/crud-introduction/
1. Embedded Data Models
2. Normalized Data Models using References
Source: http://docs.mongodb.org/manual/core/read-operations-introduction/
db.collection.find()
SQL
Source: http://docs.mongodb.org/manual/core/write-operations-introduction/
db.collection.insert()
SQL
db.collection.update()
SQL
db.collection.remove()
SQL
db.collection.mapReduce()
Superheroic JavaScript MVW Framework
AngularJS is what HTML would have been, had it been designed for building web-apps. Declarative templates with data-binding, MVW, MVVM, MVC, dependency injection and great testability story all implemented with pure client-side JavaScript!
<!DOCTYPE html>
<html>
<head>
<title>Hola Mundo, AngularJS - CERN Spring Campus 2014</title>
<script type="text/javascript" src="angular.min.js"></script>
</head>
<body ng-app>
Name: <input type="text" ng-model="name" />
<h1>Hola {{ name }}</h1>
</body>
</html>
Demo
Automatic synchronization of data between the model and view components
Source: http://docs.angularjs.org/guide/databinding
Formats the value of an expression for display to the user
{{ expression | filter1 | filter2 }}
<body ng-app>
Name: <input type="text" ng-model="name" />
<h1>Hello {{ name }}</h1>
<h4>Hello {{ name | uppercase }}</h4>
<h4>Hello {{ name | lowercase }}</h4>
</body>
Demo
Contains presentation logic and binds the view with the model using scopes
<div ng-controller="ChatController">
Message: <input type="text" ng-model="newMessage"/>
<button ng-click="add()">Add</button>
<h2>Messages</h2>
<ul>
<li ng-repeat="message in messages"> {{ message }} </li>
</ul>
</div>
function ChatController($scope) {
$scope.messages = ["I <3 sidra", "Save the whales!"];
$scope.add = function() {
$scope.messages.push($scope.newMessage);
$scope.newMessage = "";
}
}
ContactController is nothing but a plain vanilla JavaScript function.
There is an object $scope which we pass as an argument. This object is used to bind the controller with view. It decouples the view from the controller
Initially, we set the initial state of the angular scope. We then define the add() function, which is bound to Add button using an attribute ng-click. ng-click binds the click event on the button or link or any clickable element with the function that is defined within $scope. So in this case, whenever Add button is clicked, the add() method on $scope will be called.Demo
Logical entities used to structure your application
var myModule = angular.module('myModule',[]);
myModule.controller('ChatController', function($scope) {
// Controller logic
});
Singleton objects or functions that carry out specific tasks
var chatApp = angular.module('chatApp', []);
chatApp.service('ChatService', function() {
this.getLastMessages = function() {
// Ajax call to read messages from database
return [
"I <3 sidra",
"Save the whales!"
]
}
this.saveMessage = function(message) {
// Ajax call to save message to the database
}
});
If your controller is also responsible for making ajax calls to fetch and update data, this is a violation of the SRP principle.
Logic like that (and other business logic) should instead be abstracted out into a separate service, then injected into the objects that need to use it.Components are created by the container and provided (injected) as requested
var chatApp = angular.module('chatApp', []);
chatApp.service('ChatService', function() {
// ...
});
chatApp.controller('ChatController', function($scope, ChatService) {
$scope.messages = ChatService.getLastMessages();
$scope.add = function() {
ChatService.save($scope.newMessage);
$scope.messages.push($scope.newMessage);
$scope.newMessage = "";
}
});
Extend the HTML vocabulary
<pacman></pacman>
var app = angular.module('app',[]);
app.directive('pacman', function() {
return {
restrict: 'E', // E = Element, A = Attribute, C = Comment
replace: true,
template: "<div><img src='pacman.gif'/></div>"
};
});
var blink = angular.module('blink', [])
.directive('blink', function($timeout) {
return {
restrict: 'E',
transclude: true,
scope: {},
controller: function($scope, $element) {
function showElement() {
$element.css("display", "inline");
$timeout(hideElement, 1000);
}
function hideElement() {
$element.css("display", "none");
$timeout(showElement, 1000);
}
showElement();
},
template: '',
replace: true
}
});