Академический Документы
Профессиональный Документы
Культура Документы
com Node.js
Charles Viegas
charles.viegas@codate.com.br
@charlesviegas
Referncias
nodejs.org
http://expressjs.com/
https://github.com/expressjs/body-parser
https://github.com/expressjs/session
Livro: Node.js: aplicaes web real-time com Node.js
Caio Ribeiro
Casa do cdigo
INTRODUO AO NODE.JS
O que o Node.js?
Javascript no lado do servidor
Construdo sobre o engine V8 do Chrome
Executa por linha de comando
Projetado para alta concorrncia
Single thread
No bloqueante
Utiliza o framework CommonsJS
No bloqueia IO
Esperar pedidos de I/O degrada a performance.
O Node usa evento em JS para anexar retornos a chamadas
de IO.
Exemplo
BLOQUEANTE
NO BLOQUEANTE
...
String sql = "SELECT c FROM Contato";
Query q= em.createQuery(sql);
Event Loop
Ao invs de threads, o Node usa um loop de eventos,
aliviando o overhead da troca de contexto.
Instalao e Configurao
Acesse o site http://nodejs.org
Faa download do executvel e instale de forma padro
Verifique se a instalao funcionou corretamente executando
os comandos:
node version
npm --version
Prtica 1 - Ol Javaneiros
Abra o terminal e navegue para a pasta:
curso\pratica1
NPM
Node Package Manager
Gerencia os mdulos do node, baixando da web os mdulos e suas
dependncias
package.json
O Node utiliza o arquivo package.json para descrever os
metadados do projeto.
Nome, verso, dependncias
package.json
{
"name": nome_do_projeto",
"description": "Meu primeiro app em Node.js",
"author": Charles Viegas <charles@email.com>",
"version": "1.0.0",
"private": true,
"dependencies": {
"modulo-1": "1.0.0",
"modulo-2": "~1.0.0",
"modulo-3": ">=1.0.0"
},
"devDependencies": {
"modulo-4": "*"
}
"name": casalista",
"description": App para lista de casamento em Node.js",
"author": Seu Nome <seuemail@email.com>",
"version": "1.0.0",
"private": true
Objetos globais
global: assim como nos browsers o Node tambm possui um
contexto de alto nvel.
process: contm os dados do processo de execuo.
console: usado para imprimir mensagens nas sadas de fluxo
padres.
Buffer: usado para manipular dados binrios.
require: usado para importao de mdulos
Objetos globais
__filename: o nome do arquivo que est sendo executado
__dirname: o nome do diretrio que reside o arquivo que est
sendo executado.
module: uma referncia para o mdulo corrente.
CommonJS
O Node utiliza nativamente o padro CommonJS para
organizao e carregamento dos mdulos.
modulo1.js
var m2 = require(./modulo2.js);
m2(Ola Javaneiros);
modulo2.js
module.exports = function(msg){
console.log(msg);
}
DOMINANDO EXPRESS
O que o Express?
Escrever cdigo usando a API HTTP do Node muito
trabalhoso.
O Express um mdulo para desenvolvimento de aplicaes
web de grande escala.
Caractersticas do Express
MVR (Model-View-Routes)
MVC (Model-View-Controller)
Roteamento de urls via callbacks
Middleware
Interface RESTFul
Suporte a File Uploads
Integrao com Template Engines
Mdulos do Express
A partir da verso 4, o Express passou a ser distribudo em vrios mdulos, sendo
eles:
express: Mdulo principal do express.
express-load: Carregamento dinmico de arquivos JS.
express-session: Controle de sesses do usurio.
method-override: Traduz mtodo POST para PUT e DELETE.
body-parser: Parser de campos do html para objeto JSON.
cookie-parser: Parser de cookie para objeto JSON.
ejs: Engine de template.
Definindo views
...
// Configuraes futuras
...
// Define a pasta public para contedo esttico
app.use(express.static(__dirname + "/public"));
...
...
// Responde ao acessar o localhost:3000/
app.use("/", function(req, res){
res.send("Ola Javaneiros");
});
...
Express-load
Utilizaremos o express-load que carrega modulos dentro da
instncia do express simplementes informando a pasta onde
estas scripts esto.
Portanto, ao invs de usar o require(nome_do_modulo), ns
utilizaremos o express-load para esta funo.
Express-load
// Importa o mdulo express-load
var express = require("express"),
load = require("express-load"),
app = express();
...
// Carrega todas as scripts da pasta controller e routes
load("controllers")
.then("routes")
.into(app);
Prtica 7 Express-load
Adicione o express-load conforme slides anteriores.
Reinicie o node visualizar as alteraes.
Criando Roteadores
comum que os roteamento no express fiquem separados em
mdulos externos para melhorar a legibilidade do cdigo.
Portanto iremos remover o cdigo abaixo da app.js:
Criando Roteadores
E criaremos um mdulo a parte s para roteamento.
module.exports = function (app) {
var home = app.controllers.home;
app.get("/", home.index);
app.post("/entrar", home.entrar);
};
Criando Controladores
Os controladores controlam a sequncia de execuo e a navegao entre
as pginas.
Tambm recomendvel a separao da sua lgica num mdulo separado.
};
};
return HomeController;
Prtica 8 Roteadores e
Controladores
Crie os roteadores e controladores conforme slides
anteriores.
header.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Javaneiros - Lista de presentes de casamento</title>
<link rel="stylesheet" href="/bootstrap/css/bootstrap.css"/>
<link rel="stylesheet" href="/bootstrap/css/bootstrap-theme.css"/>
<link rel="stylesheet" href="/app/css/style.css" />
</head>
<body>
footer.ejs
<footer class="navbar navbar-default navbar-fixed-bottom">
<div class="container">
Javaneiros 2014
</div>
</footer>
<script src="/bootstrap/js/jquery.js"></script>
<script src="/bootstrap/js/bootstrap.js"></script>
</body>
</html>
home.ejs
<% include ./header %>
<div class="container">
<form action="/entrar" method="post" role="form" class="form-signin">
<h2>Lista de presentes</h2>
<input type="text" name="noivo" placeholder="Noivo" class="form-control"
required="required" autofocus="autofocus"/>
<input type="text" name="noiva" placeholder="Noiva" class="form-control"
required="required"/>
<button type="submit"
class="btn btn-lg btn-primary btn-block">Ver lista</button>
</form>
</div>
<% include ./footer %>
Prtica 9 Views
Crie as views header, footer e home conforme slides
anteriores.
Body-parser
O express utiliza o modulo body-parser para realizar a
converso dos dados submetidos por um formulrio html em
objeto JSON.
Body-parser
var express = require("express"),
bodyParser = require("body-parser"),
load = require("express-load"),
app = express();
Express-session
Recurso que permite manter dados do usurio no servidor.
Para acessar o objeto a ser mantido na sesso basta
acessar req.session
Express-session
var express = require("express"),
bodyParser = require("body-parser"),
load = require("express-load"),
expressSession = require("express-session"),
app = express();
app.use(expressSession({
secret: "keyboard cat",
resave: false,
saveUninitialized: true
}));
...
Manipulando session
Agora iremos gravar na sesso do usurio os dados
submetidos pela tela de home.
Para isso, iremos alterar o controlador do home.
Manipulando Session
...
var HomeController = {
...
entrar: function (req, res) {
var lista = {
noivo : req.body.noivo,
noiva : req.body.noiva,
presentes : []
};
req.session.lista = lista;
res.redirect("/presentes");
}
};
...
routers\presente.js
module.exports = function (app) {
var presentes = app.controllers.presentes;
app.get("/presentes", presentes.index);
app.get("/comprar/:id", presentes.comprar);
app.post("/presentes", presentes.incluir);
};
controllers\presente.js
module.exports = function (app) {
var PresentesController = {
index: function (req, res) {
res.render("presentes", {presentes: req.session.lista.presentes});
},
incluir: function (req, res) {
var lista = req.session.lista;
var presente = {
nome: req.body.nome,
valor: req.body.valor
};
lista.presentes.push(presente);
res.redirect("/presentes");
},
comprar: function (req, res) {
var id = req.params.id;
req.session.lista.presentes[id].comprado = true;
res.redirect("/presentes");
}
};
return PresentesController;
};
view\presentes.ejs
<% include ./header %>
<div class="container">
<div class="page-header">
<h1>Lista de presentes</h1>
</div>
<div class="row">
<! ****************** Formulrio -->
</div>
<div class="row">
<! ****************** Tabela -->
</div>
<div class="row">
<a href="/">Sair</a>
</div>
</div>
<% include ./footer %>
view\presentes.ejs - formulrio
<div class="col-xs-12">
<form action="/presentes" method="post" role="form">
<div class="row">
<div class="col-xs-4">
<input type="text" name=nome" placeholder="Presente"
class="form-control"/>
</div>
<div class="col-xs-4">
<input type="text" name=valor" placeholder="Valor"
class="form-control"/>
</div>
<div class="col-xs-4">
<button type="submit" class="btn btn-default">Incluir</button>
</div>
</div>
</form>
</div>
view\presentes.ejs - tabela
<div class="col-xs-12">
<table class="table table-bordered table-striped">
<thead><tr>
<th>Presente</th> <th>Valor</th><th>Ao</th>
</tr></thead>
<tbody>
<% presentes.forEach(function(presente, index) { %>
<tr>
<td><%- presente.nome %></td> <td><%- presente.valor %></td>
<td>
<% if (!presente.comprado) {%>
<a href="/comprar/<%- index %>">Comprar</a>
<%}%>
</td>
</tr>
<% }) %>
</tbody>
</table>
</div>
Prtica 12 Final
Crie o roteador, controlador e a view para a tela de presentes
conforme slides anteriores.