This document provides an introduction to node.js, Express, Jade, MongoDB, and mongoose. It discusses installing and using these technologies to build a web application with a backend server in JavaScript. Node.js is introduced as a way to develop server-side applications with JavaScript. Express is presented as a web application framework that can be used with Node.js. Jade is described as an HTML templating language. MongoDB is explained as a document-oriented NoSQL database, and mongoose is an ODM that provides an interface to work with MongoDB from Node.js applications.
2. The "teacher"
SUPINFO
B1 – B2 Caen (France)
B3 San Francisco (California)
M1 – M2 London (UK)
Web developer
Global Lab Manager of SUPINFO Web Laboratory
Games oriented developer and Vanilla JavaScript lover
http://adriengueret.no-ip.org/
https://twitter.com/AdrienGueret
3. A busy program
Some JavaScript revisions
Look at node.js
Discovery of Express framework
HTML templates with Jade
NoSQL and mongoDB
Using databases with mongoose
5. Functions are variables like other
//We store a function
var hello = function (name) {
alert('Hello ' + name + '!');
};
//We call this variable-function !
hello('World'); //Display«Hello World!»
6. Go further…
//A function with a function as parameter…
var callFunction = function (callback) {
callback('World');
};
callFunction(hello);
//Also display«Hello World!»
7. JSON format
var user = {
"first_name": "Jean",
"last_name": "Peplu",
"age": 22
};
alert('Hello ' + user.first_name + '!');
// «Hello Jean!»
8. JavaScripts objects
var user = {
first_name: "Jean",
last_name: "Peplu",
sayHello: function () {
alert('Hello ' + this.first_name + '!');
}
};
user.sayHello(); // «Hello Jean!»
10. A young technology
Created by Ryan Dahl in 2009
Current version: 0.8.21
A "package" containing V8 JavaScript engine
Allow us to develop server-side with JavaScript!
13. A simple Web server
var http = require('http'),
port = 1337,
server = http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('Hello World!');
});
server.listen(port);
//A nice log in the terminal
console.log('Server listening at port ' + port + '.');
>node server.js
14. request and response are useful parameters
request
Give some information about HTTP request
request.method, request.url…
response
Send information to the client
response.writeHead()…
Read the doc! http://nodejs.org/api/http.html
15. Your turn!
Create a basic Web server
3 different pages
Home page when visitor is on the root of your server
A test page on the URL /test
An error page (404) otherwise
17. What is Express?
Web application framework
Current version: 3.0
http://expressjs.com/
Very simple installation:
18. Previous exercise with Express
var port = 1337,
express = require('express'),
server = express(),
writePage = function (title, body) {
//We admit this function returns an HTML string
};
server
.get('/', function (req, res) {
res.send(200, writePage('Home', 'Welcome home!'));
})
.get('/test', function (req, res) {
res.send(200, writePage('Test page', 'It works!'));
})
.listen(port);
19. Retrieve GET parameters
We get values thanks to req.query[parameter name]
//Listen for localhost:1337/farms/?id=X
server
.get('/farms/', function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end(Farm id: #' + req.query.id);
});
20. Sexier: parameters in the URL
: + parameter name
We get values thanks to req.params[parameter name]
//Listen for localhost:1337/farms/X
server
.get('/farms/:id', function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end(Farm id: #' + req.params.id);
});
21. Retrieve POST parameters
Tell the server we want to get these parameters:
server.use(express.bodyParser());
We‟ll use the post() method (no longer get())
We get values thanks to req.body[parameter name]
server
.post('/farms/add', function (req, res) {
res.send(200, 'Nom reçu : ' + req.body.farm_name);
});
22. Public files
Also called "static" files
Images, CSS, JavaScript…
How to link them with our HTML files?
Put them in a folder name /public (or another name, it‟s your choice!)
Find an alias (once again, you choose which one!) to this folder
Indicate the use of this alias to serve this folder
server
.use(
'/static',
express.static( __dirname + '/public')
);
23. Diagram of a typical case
Requests
Main server
The visitor
Works with
Manages the HTTP server
25. Jade
HTML template
http://jade-lang.com/
Another simple installation:
Documentation: https://github.com/visionmedia/jade#a6
Interactive doc: http://naltatis.github.com/jade-syntax-docs/
26. Why using a template?
To be more with the spirit of MVC architecture
"Cleaner" code
doctype 5
html(lang="en")
head
title My page title
body
h1#title Jade - node template engine
p.desc Hello World! <br />
img(src="/static/images/ocarina.png")
27. Call a Jade template with Express
Put .jade files in the folder /views
Tell the server to use Jade engine
Call render() to display a .jade file
server
.engine('jade', require('jade').__express)
.get('/', function (req, res) {
res.render('./sample.jade');
//Path of the file : /myProject/views/sample.jade
});
28. Display variables with Jade
Send variables thanks to the method render():
server
.get('/farms/:id', function (req, res) {
res.render('./farm_details.jade', {
"farm_name" : "My wonderful farm",
"farm_value" : 30000
});
});
With Jade: use the #{variable_name} syntax:
h1 #{farm_name}
p Value of this farm is:
strong #{farm_value}
€
29. Display a list of values
server
.get('/farms/', function (req, res) {
res.render('./all_farms.jade', {
"all_farms_id" : [1, 6, 15, 21, 34, 42, 55]
});
});
In Jade: use the each … in syntax:
ul
each farm_id in all_farms_id
li Farm ##{farm_id}
30. Your turn!
Install Express
Install Jade
Create a “Register user” form
This form must redirect to its own page
It sends data with POST method
The target page just displays sent data
Oh, and please display a nice picture
31. Diagram of a typical case
Requests
Main server
The visitor
Works with
Asks for a template
Manages the HTTP server
Send HTML
HTML template
33. What is mongoDB?
A document-oriented database
Use the JSON format
{
http://www.mongodb.org/ "first_name": "Jean",
"last_name": "Peplu",
"age": 22
}
34. A bit of vocabulary…
SQL term mongoDB term
Database Database
Table Collection
Row / Entry Document
Column Field
35. Let‟s install mongoDB
http://www.mongodb.org/downloads
Extract the archive where you want to
Optional: add mongoDB path to your system PATH
36. Let‟s install mongoDB (we‟ve almost done!)
Create C:datadb folder (or /data/db according to your OS)
Run mongoDB server via the console: use the mongod command
DO NOT CLOSE THE CONSOLE ONCE
MONGODB IS LAUNCHED!
38. Diagram of a typical case
Requests
Main server
The visitor
Works with
Asks for a template Works with database
Manages the HTTP server
Send HTML Send data
Database
HTML template
39. One more tool: mongoose
Because we love to install stuff!
40. What is mongoose?
An ODM (Object Data Modeling)
Allow us to manipulate "real" objects
Current version: 3.5
Another very easy installation with npm:
http://mongoosejs.com/
41. A basic project structure
We have already created a /views folder
Let‟s create a /models one!
42. The connection file to the database
Let‟s create our own module /models/getMongoose.js
var mongoose = require('mongoose');
mongoose.connect('localhost', 'myDatabase');
exports.mongoose = mongoose;
To use it in another file:
var mongoose = require('./models/getMongoose.js').mongoose;
43. Model construction
1) Define a schema
2) Link this schema to a new model
var mongoose = require('./getMongoose.js').mongoose,
PlayerSchema = mongoose.Schema({
first_name : String,
last_name : String,
age : Number
}),
PlayerModel = mongoose.model('Player', PlayerSchema);
exports.Player = PlayerModel;
44. Create a document
1) Get the model to use
2) Create a new instance from this model ( = a document)
3) And save it!
var Player = require('./models/Player.Model.js').Player,
jean = new Player({
"first_name": "Jean",
"last_name": "Peplu",
"age": 22
});
jean.save(function (error, user) {
if (error) { console.log(error); }
else { console.log(Player "' + user.first_name + '" added!'); }
});
45. How to check everything went well
Using mongoDB in the console:
46. A little more structure
var PlayerSchema = mongoose.Schema({
email : {
type : String,
required : true,
unique : true,
trim : true
},
age: {
type : Number,
default : 13,
min : 13,
max : 110
}
});
List of setters for Strings:
http://mongoosejs.com/docs/api.html#schema-string-js
47. Your turn!
Install mongoDB and mongoose
Modify your code from previous exercise in order to save
data sent by your form
Check with your console that users are saved!
48. Retrieve data
Usage of queries builders
var Player = require('./models/Player.Model.js').Player,
query = Player.find();
query.exec(function (error, players) {
if (error) { console.log(error); }
else {
//Do something with the list of all players
}
});
49. Filter data
Directly with find()
var Player = require('./models/Player.Model.js').Player,
query = Player.find({
"first_name": "Jean"
});
Or with where()
query = Player.where('first_name', 'Jean');
Using several where()
query = Player.where('first_name', 'Jean')
.where('age', 20);
50. Filter data: other methods
Greater or equal than, lower or equal than:
query = Player.where('age')
.gte(18)
.lte(40);
Get by id:
var user_id = '5117ac79cf85d67c21000001';
Player.findById(user_id, function (error, player) {
if (error) { console.log(error); }
else if (!player) { console.log(„Player not found'); }
else { //Do something with the user }
});
And a lot of other methods… Read the documentation!
http://mongoosejs.com/docs/api.html#model_Model.find
http://mongoosejs.com/docs/api.html#query-js
51. Your turn!
Update your code from the previous exercise in order to
match these requirements:
Home page displays all your users
Below this list is a link to the register form
If an error occurs while an user is being added to the
database, visitor is redirected to the form
In order to know how to perform redirections, you should read
Express documentation!
http://expressjs.com/api.html
52. Tables relations
Using the ObjectId type
Indicate a reference model
var mongoose = require('./getMongoose.js').mongoose,
FarmSchema = mongoose.Schema({
owner : {
type : mongoose.Schema.Types.ObjectId,
ref : 'Player'
}
});
53. Linked documents need to be "populated"
Get an owner from one of his farm:
Farm.findById(farm_id)
.populate('owner')
.exec(function (error, farm) {
if (error) { console.log(error); }
else if (!farm) { console.log('Farm not found'); }
else {
console.log(farm.owner.first_name);
}
});
To know more, once again… Documentation!
http://mongoosejs.com/docs/populate.html
54. And now, the reverse…
Get a player‟s farms:
Farm.where('owner', player_id)
.exec(function (error, farms) {
if (error) { console.log(error); }
else {
//Do something with the list of farms
}
});
Think MVC: separate Models from Controllers!
55. Static methods
Using the property statics from schemas
http://mongoosejs.com/docs/guide.html#statics
FarmSchema = mongoose.Schema({
owner : {
type : mongoose.Schema.Types.ObjectId,
ref : 'Player'
}
});
FarmSchema.statics.findByOwnerId = function (owner_id, callback) {
this.where('owner', owner_id).exec(callback);
};
//Call the static method
Farm.findByOwnerId('1R@nD0m!d', function (error, farm) {
//Do something
});
56. Your turn!
Update your code from the previous exercise in order to
manage farms:
Create a model for these farms
On Home page, each username you have displayed must now
be a link to the list of farms owned by this user
Below this list is another link to a form allowing to create and
add a new farm to the corresponding user
57. Diagram of a typical case
Requests
Main server
The visitor
Works with
Database
Asks for a template Works with database Interacts
Manages the HTTP server
Send HTML Send data
Object Data Modeling
HTML template
58. Thank you!
Do you have any questions?
adrien.gueret@supinfo.com
And don‟t forget: read documentations!
Editor's Notes
Developing with node.js means using a lot of callbacks: you must understand how it work!
Note that quotes are no longer mandatory!
Since it’s a young technology, there are a lot of updates. At the time you will read this course, a newer version will be probably released.
The node.js command prompt has been installed for Windows only. Other OS should be able to use node directly with their native console.
Windows launches a security alert the first time we run node.js.
ConcerningMVC: template are pure views and don’t allow us to put complex logical. Purpose of templates is just to display HTML and we can’t do anything else!
We MUST have a /views folder, don’t rename it!
Add mongoDB in your system PATH will allow you to call in an easier way from your console.
It’s possible to change the path /data/db to another one.To do that, call mongod wit the --dbpath option:mongod --dbpath /other/path/to/db
Please note the ObjectId field: it’s an automatically generated and unique field.
Don’t forget to call query() method!
Note that we use findById() with a callback: if we provide it, we don’t need to call exec() method!
Tables relations can also be made by using subdocuments : http://mongoosejs.com/docs/subdocs.html
We define a static method in the schema, but we call it from the model!