SlideShare una empresa de Scribd logo
1 de 105
@flaviohalmeida
flavio.almeida@caelum.com.br
FLÁVIO ALMEIDA
Java
C#
Python
Ruby
Groovy
JavaScript
Desenvolvedor Java à procura da menor
impedância para construção de
aplicações web
Once upon a time…
Impedância?
Impedância
“Discrepância da estrutura dos dados
armazenados no banco de dados e as
estruturas de dados em memória”
- Martin Fowler
Impedância
ESTRUTURA TABULAR E RELACIONAL, SQL
POJO (PLAIN OLD JAVA OBJECTS)
JSON (JAVASCRIPT OBJECT
NOTATION)
Isomorphic JavaScript
Back-end e front-end
compartilham o
mesmo código
JavaScript é considerada a
língua franca da web
Língua Franca
É aquela que um grupo multilíngue de
pessoas intencionalmente adota ou
desenvolve para que todos consigam
sistematicamente comunicar-se uns com
os outros.
Língua franca ou torre de babel?
ESTRUTURA TABULAR E RELACIONAL, SQL
POJO (PLAIN OLD JAVA OBJECTS)
JSON (JAVASCRIPT OBJECT
NOTATION)
"Não são as respostas que
movem o mundo, são
as perguntas”
— Albert Einstein
Testes de unidade
Testes de integraçãoOne commit deploy
Integração contínua
(Travis)
Grunt
(Automação)
Bootstrap
Karma
(Jasmine)
Protractor
(Selenium)
AngularJS
To be or not to be
MEAN?
Tradução da palavra mean
Adjetivos
inferior, insignificante, malvado, mediano,
pobre, ruim, sórdido, etc.
Significado do acrônimo MEAN
MongoDB
Express
AngularJS
Nodejs
Contexto Histórico
Contexto Histórico
Era do AJAX
2005
"Nova abordagem de criação
de páginas web"
- Jesse James Garret
Era do SPA
2005
SINGLE PAGE APPLICATION
"Elementos de interface e lógica da
aplicação são criados e executados
no cliente"
—Steve Yen
Era do Extreme Go Horse
2005
2010
Backbone
Angular
Era dos Frameworks
2009
2011
Batman
2012
Ember
a) Popularidade meteórica
b) Pioneiro na injeção de dependências
c) Solução própria para criação de módulos
d) Sistema próprio de rotas
e) Two-way data binding
f) Ferramentas para testes
Era "The Book is on the Table"
2013…
Progressive Enhancement
X
SPA
"Pensamos no que deveria
ser e fechamos os olhos
para o que é"
- Michel Maffesoli
SPA's chegaram para ficar, quer
você queira ou não
Hoje é a “palavra de ordem“ em
aplicações híbridas
Paralelamente…
2009
Bancos que não se baseiam em
esquemas (Eric Evans)
N SQL
2009
Banco NoSQL baseado em documento BSON,
MUITO semelhante ao JSON, porém com mais
tipos
2009
Boa parte da responsabilidade das regras de
validação fica nas mãos dos desenvolvedores.
2009
Quero aplicações Web!!!
2010
2011
var mongoose = require('mongoose');
var schema = mongoose.Schema({
nome: {
type: String,
required: true
},
email: {
type: String,
required: true,
index: {
unique: true
}
}
});
return mongoose.model('Contato', schema);
2011
2012
VALERI KARPOV
Cunhou o acrônimo MEAN para denotar as
tecnologias utilizadas durante uma competição
de hackathron que venceu.
MEAN
2012
VALERI KARPOV
Ascot Project
Bookalokal
Vantagens constatadas durante o
Hackathon
SPA desde o início
Menor impedância
API REST
Isomorphic JavaScript*
* não era para você conseguir ler isso!
SPA desde o início
ngRoute
(default)
ui-router
(extensão)
SPA desde o início
<!— index.html —>
<html ng-app="minhaApp">
<head>
(…)
</head>
<body>
<ng-view>
</ng-view>
</body>
</html>
<!-- partials/cadastro.html -->
<h1>Cadastro de fotos</h1>
<form>
(...)
</form>
<!-- partials/listagem.html -->
<h1>Listagem de fotos</h1>
SPA desde o início
angular.module('minhaApp', ['ngRoute'])
.config(function($routeProvider) {
$routeProvider.when('/fotos', {
templateUrl: 'partials/listagem.html',
controller: 'FotosController'
});
$routeProvider.when('/fotos/new', {
templateUrl: 'partials/cadastro.html',
controller: 'FotoController'
});
});
Menor impedância
ESTRUTURA TABULAR E RELACIONAL
Autor autor = new Autor();
autor.setNome(…);
{
"_id": "1"
"nome": "Flávio Almeida"
}
OUTROS
Navegador
(JSON)
Banco
(SQL)
Servidor
(Object)
Menor impedância
{
"_id": ObjectId("5303e0649fd139619aeb783e")
"nome": "Flávio Almeida"
}
{
"_id": "5303e0649fd139619aeb783e"
"nome": "Flávio Almeida"
}
{
"_id": "5303e0649fd139619aeb783e"
"nome": "Flávio Almeida"
}
MEAN STACK
Navegador
(JSON)
Banco
(BSON)
Servidor
(JSON)
Menor impedância
$http('/v1/fotos')
.then(function(fotos){
$scope.fotos = fotos;
});
app.get('v1/fotos', function(req, res){
db.collection('contatos').find({},
function(erro, contatos){
if(erro) throw err;
res.json(contatos);
}
});
};
Client
(Angular)
Server (API REST)
(Express/MongoDB driver)
<img
ng-repeat="foto in fotos"
ng-src=“{foto.src}">
Performance
Escalabilidade
Estado no cliente, servidor stateless
Single thread e non-blocking I/O
non-blocking I/O
Tudo roda em paralelo, exceto seu código!
Blocking Vs non-blocking
I/O
db.collection('contatos').find({},
function(erro, contatos) {
console.log(contatos);
}
);
console.log('FIM');
var contatos = db.collection('contatos').find({});
console.log(contatos);
console.log('FIM');
Pseudo Blocking I/O
Non-blocking I/O
Mas na prática, é tudo
essa maravilha?
Não há um Scaffold
consolidado
mean.io
VS
mean.js
Você já implementou um DAO, não importa a
linguagem?
DAO pattern
dao.porNome = function(nomeProcurado, cb) {
db.collection('contatos')
.findOne({nome : procurado}, function(erro, contato) {
if (erro) cb('Não foi possível…', null);
cb(null, contato);
});
};
dao.dependenteDoContato = function(contato, cb) {
db.collection('dependentes')
.find({contatoId : contato_id}, function(erro, dependente) {
if (erro) cb('Não foi possível…', null);
cb(null, dependente) ;
});
};
dao.adicionaBeneficio = function(dependente, cb) {
db.collection('beneficios')
.insert(dependente, function(erro) {
if (erro) cb('Não foi possível…’, null);
cb(null, true);
});
};
Callback HELL
dao.porNome('Flávio Almeida', function(erro, contato) {
if(erro) throw console.log(erro);
dao.dependenteDoContato(contato, function(erro, dependente) {
if(erro) throw console.log(erro);
dao.adicionaBeneficio(dependente, function(erro, adicionado){
if(erro) throw console.log(erro);
if (adicionado)
console.log('Benefício adicionado');
});
});
});
Callback HELL
dao.porNome('Flávio Almeida', function(erro, contato) {
if(erro) throw console.log(erro);
dao.dependenteDoContato(contato, function(erro, dependente) {
if(erro) throw console.log(erro);
dao.adicionaBeneficio(dependente, function(erro, adicionado){
if(erro) throw console.log(erro);
if (adicionado)
console.log('Benefício adicionado');
});
});
});
Synchronous Heaven
try {
var contato = dao.porNome('Flávio Almeida');
var dependente = dao.depententeDoContato(contato);
console.log(dao.adicionaBeneficio(dependente));
} catch(erro) {
console.log(erro);
}
Callback HELL
No cliente (browser) acontece a mesma coisa!
Mas tem cura doutor?
Só se você fizer uma promessa!
Callback HELL
dao.porNome('Flávio Almeida', function(erro, contato) {
if(erro) throw console.log(erro);
dao.dependenteDoContato(contato, function(erro, dependente) {
if(erro) throw console.log(erro);
dao.adicionaBeneficio(dependente, function(erro, adicionado){
if(erro) throw console.log(erro);
if (adicionado)
console.log('Benefício adicionado');
});
});
});
Promise Pattern
dao.porNome('Flávio Almeida')
.then(dao.depententeDoContato)
.then(dao.adicionaBeneficio)
.then(function(adicionado) {
if (adicionado)
console.log('Benefício adicionado’);
})
.catch(function(erro) {
console.log(erro);
});
DAO pattern
dao.porNome = function(nomeProcurado, cb) {
db.collection('contatos')
.findOne({nome : procurado}, function(erro, contato) {
if (erro) cb('Não foi possível…', null);
cb(null, contato);
});
};
dao.dependenteDoContato = function(contato, cb) {
db.collection('dependentes')
.find({contatoId : contato_id}, function(erro, dependente) {
if (erro) cb('Não foi possível…’, null);
cb(null, dependente) ;
});
};
(…)
DAO + Promise Pattern
dao.porNome = function(nomeProcurado) {
return Q.Promise(function(resolve, reject) {
db.collection('contatos')
.findOne({nome : procurado}, function(erro, contato) {
if (erro) reject(erro);
resolve(contato);
});
});
};
dao.dependenteDoContato = function(contato) {
return Q.Promise(function(resolve, reject) {
db.collection('dependentes')
.find({contatoId : contato_id}, function(erro, dependente) {
if (erro) reject(erro);
resolve(dependente) ;
});
});
};
(...)
Promise Pattern
dao.porNome('Flávio Almeida')
.then(dao.depententeDoContato)
.then(dao.adicionaBeneficio)
.then(function(adicionado) {
if (adicionado)
console.log('Benefício adicionado');
})
.catch(function(erro) {
console.log(erro);
});
Synchronous Heaven
try {
var contato = dao.porNome('Flávio Almeida');
var dependente = dao.depententeDoContato(contato);
console.log(dao.adicionaBeneficio(dependente));
} catch(erro) {
console.log(erro);
}
Mas eu ainda quero o paraíso!
Promise Pattern
dao.porNome('Flávio Almeida')
.then(dao.depententeDoContato)
.then(dao.adicionaBeneficio)
.then(function(adicionado) {
if (adicionado)
console.log('Benefício adicionado’);
})
.catch(function(erro) {
console.log(erro);
});
Q.async(function*() {
try {
var contato = yield dao.porNome('Flávio Almeida');
var dependente = yield dao.depententeDoContato(contato);
console.log(yield dao.adicionaBeneficio(dependente));
} catch(erro) {
console.log(erro);
}
}).done();
É quase um paraíso
Synchronous Heaven
try {
var contato = dao.porNome('Flávio Almeida');
var dependente = dao.depententeDoContato(contato);
console.log(dao.adicionaBeneficio(dependente));
} catch(erro) {
console.log(erro);
}
Permite suspender a execução no meio de uma
função para mais tarde retomá-la
Generator
Generator
function * meuGerador() {
var num1 = 1;
var num2 = 2;
var num3 = 3;
yield num1;
yield num2;
yield num3;
}
var gerador = meuGerador();
console.log(gerador.next().value); // 1
console.log(gerador.next().value) // 2
console.log(gerador.next().value) // 3
console.log(gerador.next().value) // undefined
Generators e Promises
Q.async(function*() {
try {
var contato = yield dao.porNome('Flávio Almeida');
var dependente = yield dao.depententeDoContato(contato);
console.log(yield dao.adicionaBeneficio(dependente));
} catch(erro) {
console.log(erro);
}
}).done();
Synchronous Heaven
try {
var contato = dao.porNome('Flávio Almeida');
var dependente = dao.depententeDoContato(contato);
console.log(dao.adicionaBeneficio(dependente));
} catch(erro) {
console.log(erro);
}
Mas eu ainda quero o paraíso!
Synchronous Heaven
try {
var contato = dao.porNome('Flávio Almeida');
var dependente = dao.depententeDoContato(contato);
console.log(dao.adicionaBeneficio(dependente));
} catch(erro) {
console.log(erro);
}
try {
var contato = yield dao.porNome('Flávio Almeida');
var dependente = yield dao.depententeDoContato(contato);
console.log(yield dao.adicionaBeneficio(dependente));
} catch(erro) {
console.log(erro);
}
Generators e Promises
E as ferramentas de BI do cliente?
Injection Free!
Injection Free
// Controller ExpressJS
controller.removeContato = function(req, res)
{
var _id = req.params.id;
Contato.remove({'_id' : _id}).exec()
.then(function() {
res.status(204).end();
}, function(err) {
return console.error(erro);
}
);
};
{"_id" : 5}
{"_id" : { "$ne" : null}}
Injection Free???
// Controller ExpressJS
controller.removeContato = function(req, res)
{
var _id = req.params.id;
Contato.remove({'_id' : _id}).exec()
.then(function() {
res.status(204).end();
}, function(err) {
return console.error(erro);
}
);
};
{"_id" : { "$ne" : null}}
Agora, Injection Free
// Controller ExpressJS
var sanitize = require(‘mongo-sanitize');
controller.removeContato = function(req, res)
{
var _id = sanitize(req.params.id);
Contato.remove({'_id' : _id}).exec()
.then(function() {
res.status(204).end();
}, function(err) {
return console.error(erro);
}
);
};
Carlinhos Aguiar, document
replace é uma …
PÉSSIMA IDEIA,
SÍLVIO!
Document Replace
controller.salvaContato = function(req, res) {
var _id = req.body._id;
Contato.findByIdAndUpdate(_id, req.body).exec()
.then(
// código omitido
);
Document Replace
controller.salvaContato = function(req, res) {
var _id = req.body._id;
var dados = {
"nome" : req.body.nome,
"email" : req.body.email
};
Contato.findByIdAndUpdate(_id, dados).exec()
Pince os dados…
Sistema de Módulos
AMD CommonJSES6
http://addyosmani.com/writing-modular-js/
Sistema de Módulos
AMD CommonJSES6
http://addyosmani.com/writing-modular-js/
A luta deixa deixa de ser pela menor "impedância
"e passa a ser por uma standardization dentro do
ecossistema JavaScript.
MANK
Alternativas à MEAN Stack
MRKN
MyEAN
METEOR
Obrigado!
@flaviohalmeida
flavio.almeida@caelum.com.br
FLÁVIO ALMEIDA
Perguntas?

Más contenido relacionado

Similar a Flávio Almeida MEAN Stack "to be or not to be mean"

Groovy para javeiros - Migração Painless
Groovy para javeiros - Migração PainlessGroovy para javeiros - Migração Painless
Groovy para javeiros - Migração PainlessRafael Farias Silva
 
Algaworks ebook-java-ee-7-com-jsf-primefaces-e-cdi-2a-edicao-20150228
Algaworks ebook-java-ee-7-com-jsf-primefaces-e-cdi-2a-edicao-20150228Algaworks ebook-java-ee-7-com-jsf-primefaces-e-cdi-2a-edicao-20150228
Algaworks ebook-java-ee-7-com-jsf-primefaces-e-cdi-2a-edicao-20150228MoisesInacio
 
Backbone.js + Rails - Front-end e back-end conectados
Backbone.js + Rails - Front-end e back-end conectadosBackbone.js + Rails - Front-end e back-end conectados
Backbone.js + Rails - Front-end e back-end conectadosHenrique Gogó
 
PyData - Consumindo e publicando web APIs com Python
PyData - Consumindo e publicando web APIs com PythonPyData - Consumindo e publicando web APIs com Python
PyData - Consumindo e publicando web APIs com PythonBruno Rocha
 
PHPUnit e teste de software
PHPUnit e teste de softwarePHPUnit e teste de software
PHPUnit e teste de softwarericardophp
 
Produtividade em Java com Grails
Produtividade em Java com GrailsProdutividade em Java com Grails
Produtividade em Java com GrailsWanderson Oliveira
 
Rest Java One
Rest Java OneRest Java One
Rest Java OneDextra
 
Desenvolvendo com Dojo Toolkit
Desenvolvendo com Dojo ToolkitDesenvolvendo com Dojo Toolkit
Desenvolvendo com Dojo ToolkitFlávio Lisboa
 
M5-Desenvolvimento-Paginas-Web
M5-Desenvolvimento-Paginas-WebM5-Desenvolvimento-Paginas-Web
M5-Desenvolvimento-Paginas-Webdiogoa21
 
Javascript levado a serio
Javascript levado a serioJavascript levado a serio
Javascript levado a serioJaydson Gomes
 
Enterprise Java Beans
Enterprise Java BeansEnterprise Java Beans
Enterprise Java BeansRubem Azenha
 
Minicurso Ajax - 5. Semana de Informática PUC Minas São Gabriel
Minicurso Ajax - 5. Semana de Informática PUC Minas São GabrielMinicurso Ajax - 5. Semana de Informática PUC Minas São Gabriel
Minicurso Ajax - 5. Semana de Informática PUC Minas São GabrielMarcelo Linhares
 
php4android: desenvolva aplicações android em PHP
php4android: desenvolva aplicações android em PHPphp4android: desenvolva aplicações android em PHP
php4android: desenvolva aplicações android em PHPRamon Ribeiro Rabello
 

Similar a Flávio Almeida MEAN Stack "to be or not to be mean" (20)

Groovy para javeiros - Migração Painless
Groovy para javeiros - Migração PainlessGroovy para javeiros - Migração Painless
Groovy para javeiros - Migração Painless
 
Algaworks ebook-java-ee-7-com-jsf-primefaces-e-cdi-2a-edicao-20150228
Algaworks ebook-java-ee-7-com-jsf-primefaces-e-cdi-2a-edicao-20150228Algaworks ebook-java-ee-7-com-jsf-primefaces-e-cdi-2a-edicao-20150228
Algaworks ebook-java-ee-7-com-jsf-primefaces-e-cdi-2a-edicao-20150228
 
Backbone.js + Rails - Front-end e back-end conectados
Backbone.js + Rails - Front-end e back-end conectadosBackbone.js + Rails - Front-end e back-end conectados
Backbone.js + Rails - Front-end e back-end conectados
 
Realtime com node.js e socket.io
Realtime com node.js e socket.ioRealtime com node.js e socket.io
Realtime com node.js e socket.io
 
PyData - Consumindo e publicando web APIs com Python
PyData - Consumindo e publicando web APIs com PythonPyData - Consumindo e publicando web APIs com Python
PyData - Consumindo e publicando web APIs com Python
 
Debugging no Devtools
Debugging no DevtoolsDebugging no Devtools
Debugging no Devtools
 
Mini Curso Mashup Coreu
Mini Curso Mashup CoreuMini Curso Mashup Coreu
Mini Curso Mashup Coreu
 
Java Web Fácil com VRaptor
Java Web Fácil com VRaptorJava Web Fácil com VRaptor
Java Web Fácil com VRaptor
 
PHPUnit e teste de software
PHPUnit e teste de softwarePHPUnit e teste de software
PHPUnit e teste de software
 
Produtividade em Java com Grails
Produtividade em Java com GrailsProdutividade em Java com Grails
Produtividade em Java com Grails
 
Rest Java One
Rest Java OneRest Java One
Rest Java One
 
Desenvolvendo com Dojo Toolkit
Desenvolvendo com Dojo ToolkitDesenvolvendo com Dojo Toolkit
Desenvolvendo com Dojo Toolkit
 
M5-Desenvolvimento-Paginas-Web
M5-Desenvolvimento-Paginas-WebM5-Desenvolvimento-Paginas-Web
M5-Desenvolvimento-Paginas-Web
 
Javascript levado a serio
Javascript levado a serioJavascript levado a serio
Javascript levado a serio
 
Enterprise Java Beans
Enterprise Java BeansEnterprise Java Beans
Enterprise Java Beans
 
Minicurso Ajax - 5. Semana de Informática PUC Minas São Gabriel
Minicurso Ajax - 5. Semana de Informática PUC Minas São GabrielMinicurso Ajax - 5. Semana de Informática PUC Minas São Gabriel
Minicurso Ajax - 5. Semana de Informática PUC Minas São Gabriel
 
php4android: desenvolva aplicações android em PHP
php4android: desenvolva aplicações android em PHPphp4android: desenvolva aplicações android em PHP
php4android: desenvolva aplicações android em PHP
 
Java e orientação a objetos
Java e orientação a objetosJava e orientação a objetos
Java e orientação a objetos
 
Java script1
Java script1Java script1
Java script1
 
Minicurso Java
Minicurso JavaMinicurso Java
Minicurso Java
 

Flávio Almeida MEAN Stack "to be or not to be mean"

Notas del editor

  1. Flávio Almeida sou dev e instrutor Caelum, se você dar uma Googlada vocês chegam até meu repo, facebook twitter e grupos que eu participo. Quero começar um uma pequena história, pequena mesmo…
  2. Flávio Almeida sou dev e instrutor Caelum, se você dar uma Googlada vocês chegam até meu repo, facebook twitter e grupos que eu participo. Quero começar um uma pequena história, pequena mesmo…
  3. Flávio Almeida sou dev e instrutor Caelum, se você dar uma Googlada vocês chegam até meu repo, facebook twitter e grupos que eu participo. Quero começar um uma pequena história, pequena mesmo…
  4. Quem sabe o que é impedância em desenvolvimento de software?
  5. Qual banco vocês usam? MySQL, POSTGRES, SQLSERVER, ORACLE
  6. A estrutura de dados é diferente no banco, na memória do servidor e na memória do navegador. Java ORM, etc.
  7. Tornei-me um andarilho à procura da menor impedância, porque isso era importante para mim.
  8. Até que um dia eu ouvi falar de Isomorphic Java, opa! Isomorphic JavaScript
  9. Torre de babel. Por mais que eu uso ferramentas que tentam minimizar a impedância no meu Back-end, a estrutura de dados do banco e a que roda no navegador são diferentes. No back-end temos controle, mas no navegador? É terra de ninguém, ninguém não, é terra do JavaScript.
  10. Não tenho controller do browser, mas tenho controller do meu backend.
  11. Será que consigo criar aplicações profissionais com testes de unidade, aceitação, integração contínua, gerenciamento de dependências e automação de tarefas como numa aplicação profissional Java?
  12. Minhas perguntas me levaram a uma gestão, o livro MEAN. Uma aventura em busca do Isomorphic JavaScript. Esta palestra mostrar o contexto histórico da Stack, algo que não falo no livro, um overview e um posfácio dos problemas e soluções que encontrei. Do zero ao deploy
  13. Depois do lançamento do Livro, novos desafios e achados.
  14. Nenhum dev quer um sistema com essas qualidades, certo?
  15. há sempre uma motivação ou um zeitgeist (espírito do tempo) que a influencia. Eric Hobsbawn é um historiador famoso. Ele tem vários livros com o título "A era do capital”, “ Era dos impérios”, “Era dos extremos”. No meu livro eu não entro em detalhes no contexto histórico do MEAN, isso é um complemento.
  16. E se no lugar de apenas partes da app usar ajax, toda ela, inclusive a troca de páginas utilizasse essa tecnologia?(spa)
  17. Foi daí que Steven Yen cunhou o termo SPA. Na verdade, um heavy use de Ajax. Porém, JavaScript e programação assíncronas não são triviais.
  18. Cada um procurando sua solução SPA.
  19. A proliferação de SPA foi tão grande que também aumentou o code base do client. Para ajudar no SPA e também na organização do código foram criados frameworks MVC.
  20. Novos livros de renome começaram a ser lançados…
  21. Novos livros de renome começaram a ser lançados…
  22. Novos livros de renome começaram a ser lançados…
  23. Novos livros de renome começaram a ser lançados…
  24. Sim, da mesma forma que a evolução de SPA foi ocorrendo, outra revolução também foi sendo empreendida.
  25. O que é não ter esquemas? Não há coluna Tabela tem colunas e possui registros. Tabelas são documentos que possui propriedades. Documentos são agregados em coleções. Documentos dentro de uma coleção podem ter estruturas diferentes! Isso é bom, isso é ruim? Tudo depende, veremos mais à frente.
  26. É sua aplicação que deve criar esquemas e garantir dados.
  27. Plataforma JavaScript criada por Bryan Dahl. Usa a V8 (máquina virtual do Chrome) que processa o JavaScript. Considerada uma das máquinas virtuais mais sofisticadas. O mais curioso é que a NETSCAPE já havia tentando consolidar o javascript no lado do servidor com o NETSCAPE SERVER, mas naquela época havia problema de performance, inclusive o preconceito contra a linguagem, considerada “inferior”. Será que a plataforma Node.js é digna para o desenvolvimento de aplicações mais complexas? Pergunte a eles: Netscape em 1999/2000 tentou JS no lado do servidor, mais não rolou (debugar era complicado, era multithread, era compilada.
  28. MS windows 10 ARM
  29. É sua aplicação que deve criar esquemas e garantir dados.
  30. É sua aplicação que deve criar esquemas e garantir dados. falar importância de esquema
  31. Pode parecer que usar 4 tecnologias para desenvolvimento pode ser algo trabalhoso, mas provou o contrário numa competição de hackathron. São curtas competições de programação.
  32. Pode parecer que usar 4 tecnologias para desenvolvimento pode ser algo trabalhoso, mas provou o contrário numa competição de hackathron. São curtas competições de programação.
  33. Ascot Project: ferramenta para marcação de produtos em fotos. Bookalokal: aplicação web para encontrar lugares para jantar perto de você
  34. Uma ferramenta de ORM pode ser usada, para quando for depurar a aplicação a estrutura de dados é diferente nas três camadas.
  35. Estrutura de dados semelhante ou quase, depurar nas três camadas acaba se tornando algo mais fácil (obs: depurar JavaScript não é tão trivial).
  36. Single thread, como roda em paralelo?
  37. fala da promessa, se cumprir, se não cumprir
  38. Só node 0.11 com —harmony. Browser suportará também. O Q.ASYNC é um açúcar para chamar o generator.
  39. Só node 0.11 com —harmony. Browser suportará também. O Q.ASYNC é um açúcar para chamar o generator.
  40. Só node 0.11 com —harmony. Browser suportará também. O Q.ASYNC é um açúcar para chamar o generator.
  41. Só node 0.11 com —harmony. Browser suportará também. O Q.ASYNC é um açúcar para chamar o generator.
  42. Só node 0.11 com —harmony. Browser suportará também. O Q.ASYNC é um açúcar para chamar o generator.
  43. Só node 0.11 com —harmony. Browser suportará também. O Q.ASYNC é um açúcar para chamar o generator.
  44. Só node 0.11 com —harmony. Browser suportará também. O Q.ASYNC é um açúcar para chamar o generator.
  45. Imagine que o MongoDB seja indicado para a aplicação, como gerar relatório? E as ferramentas que tenho? E meu cliente que usa alguma ferramenta já paga para consultar SQL, gerar CUBO, etc?
  46. Leverage your existing SQL skillsets and BI tools including Tableau, Qlikview, MicroStrategy, Spotfire, Excel and more
  47. Qual o custo disso? Aumento da impedância. A boa notifica é que o driver retorna um JSON, porém você ainda terá que montar suas queries em SQL.
  48. Agora sim, a forma anterior é usado mais para protótipos. O problema dessa solução é que você precisará sempre fazer isso para evitar maiores problemas.
  49. Agora sim, a forma anterior é usado mais para protótipos. O problema dessa solução é que você precisará sempre fazer isso para evitar maiores problemas.
  50. Agora sim, a forma anterior é usado mais para protótipos. O problema dessa solução é que você precisará sempre fazer isso para evitar maiores problemas.