Conhecendo a stack MEAN: MongoDB, Express, Angular e Node.

Conhecendo a stack MEAN: MongoDB, Express, Angular e Node.
vitor.mattos
vitor.mattos

Compartilhe

Nos últimos anos, talvez por culpa da revolução Ajax, o JavaScript deixou de ser uma toy language e ganhou muita força. Foi nessa expansão dos horizontes da linguagem que surgiu o Node, um ambiente de execução JavaScript baseado na engine V8 da Google. Agora temos JavaScript também no lado do servidor! Node.JS segue o paradigma de programação orientada a eventos e non-blocking I/O, resultando em ótima performance para determinados cenários de aplicações real-time. Além do Node, um outro framework que vem ganhando tração é o AngularJS, da Google.

Em meio a essa expansão do JavaScript na web, foi criado o MEAN stack:

  • MongoDB - Banco de dados orientado a documentos
  • Express - Framework de desenvolvimento web para Node
  • AngularJS - Framework MVC para JavaScript
  • Node.js - Ambiente de execução JavaScript
nodejs-1024x768

Mas por que usar essa seleção de ferramentas?

Banner promocional da Alura, com chamada para um evento ao vivo no dia 12 de fevereiro às 18h30, com os dizeres

De início, temos a vantagem de não precisar saber nenhuma linguagem além do JavaScript. O que também é uma grande vantagem quando queremos utilizar um banco de dados NoSql, como o MongoDB, já que estaremos trabalhando direto com objetos muito similares ao JSON. Essas características tornam o MEAN Stack ideal para rápida prototipação de software e desenvolvimento de aplicações escaláveis. Por ser usado apenas uma linguagem bem difundida, como o JavaScript, é adequado também para desenvolvedores que não tem muita experiência com o desenvolvimento backend.

Por onde começar?

Com o MongoDB, Node, npm (node package manager) e Express instalados, vamos criar um novo projeto usando o Express e instalando os módulos mongodb e mongoose. Usaremos o mongoose para trabalhar de forma simplificada com MongoDB. No exemplo abaixo, usaremos o template engine "ejs"

express -e cadastro-de-contatos

Dentro do diretório cadastro-de-contatos, altere as dependências no arquivo package.json da seguinte maneira:

 "dependencies": { "express": "3.4.3", "ejs": "\*", "mongodb": "~1.3.19", "mongoose": "~3.8.1" } 

Agora, rode o comando npm install para baixar os módulos necessários

Primeiro, vamos iniciar o AngularJS:

 <html ng-app> 

Agora, podemos criar o formulário para adicionar novos contato, no arquivo views/index.ejs, que invocará a função adicionaContato.

 <section ng-controller='ContatosController'> <form ng-submit='adicionaContato()'> <input type='text' placeholder='nome' ng-model='contato.nome' /> <input type='tel' placeholder='telefone' ng-model='contato.telefone' /> <input type='submit' value='salvar' /> </form> </section> 

Repare que definimos que os campos de input estão vinculados a um objeto no controller, e o formulário chamará a função adicionaContato quando o submetermos. Vamos criar o ContatosController.js:

 function ContatosController($scope, $http) {

function Contato() { this.nome = ''; this.telefone = ''; }

$scope.contato = new Contato();

$scope.contatos = \[\];

$scope.adicionaContato = function() { $http.post('/contato', $scope.contato).success(function() { $scope.contatos.push($scope.contato); $scope.contato = new Contato(); }); } } 

A função adicionaContato faz um post assíncrono para /contato, enviando o objeto contato no corpo da requisição. Mas essa rota ainda não existe! Ainda temos que defini-la no servidor, no  arquivo app.js:

 app.post('/contato', routes.adicionaContato); 

Quando a requisição for feita, o contato será persistido no banco, mas ainda temos que criar a estrutura dos documentos de contato que serão gravados. Faremos isso utilizando o mongoose em nosso routes/index.js:

 var mongoose = require('mongoose'); mongoose.connect('mongodb://localhost/mean'); var Schema = mongoose.Schema;

var contatoSchema = new Schema({ nome: { type: String, required: true }, telefone: { type: String, required: true } }); 

Ainda no routes/index.js, devemos criar a função que será chamada quando o post para /contato for feito:

 exports.adicionaContato = function(req, res) { var contato = new Contato(req.body); contato.save(function(error, contato) { if(error) res.send(500);

res.send(201); }); } 

Pronto. Já estamos persistindo o contato no banco. Podemos testar nossa aplicação rodando o comando node app.js e abrindo a acessando a url http://localhost:3000/. Repare que não mapeamos o contato em momento algum, e todo o código escrito, tanto no cliente quanto no servidor, foi JavaScript.

Podemos agora fazer a listagem dos contatos. No views/index.ejs:

 <table class="table table-striped"> <tr> <th>Nome</th> <th>Telefone</th> </tr> <tr ng-repeat='contato in contatos'> <td>{{contato.nome}}</td> <td>{{contato.telefone}}</td> </tr> </table> 

Vamos também fazer a busca dos contatos no controller do Angular ContatosController.js:

 function ContatosController($scope, $http) {

// Resto do código

$http.get('/contatos').success(function(retorno) { $scope.contatos = retorno.contatos; }); } 

Estamos fazendo um get assíncrono para /contatos. Da mesma forma que fizemos com o post, temos que definir a rota no servidor, no arquivo app.js:

 app.get('/contatos', routes.listaContatos); 

E no routes/index.js, faremos a busca no banco:

 exports.listaContatos = function(req, res) { Contato.find({}, function(error, contatos) { if(error) res.send(500);

res.json({ contatos: contatos }); }); } 

Pronto! É JavaScript em todos os lados, que pode até confundi-lo, no início, de onde vai cada código!

Todo o código do artigo pode ser encontrado neste repositório.

Veja outros artigos sobre Front-end