terça-feira, 18 de agosto de 2015

Qual o sentido do node, do npm e tudo mais (knex, bower, postgresql, angular)

O node veio pra ficar, e se você prestar atenção nos anos anteriores e nos que virão você vai ver que essa plataforma está aqui pra ficar e está com tudo.

O que vou mostrar aqui é como levantar uma aplicação minimamente usável. Como diria o Jake, vai ser legal, cara!

Vamos aos ingredientes:
  1. Fedora 22 ou superior
  2. Atom text editor
O resto das coisas (postgresql, node, npm) o fedora traz. Valendo? 


Comece instalando o Atom (o pacote rpm):

Quando o download terminar simplemente clique duas vezes no pacote rpm.

Daí abra um terminal e instale o node e o npm:
sudo dnf install nodejs npm


Instale ainda o postgresql:
sudo dnf install postgresql-server


Temos quase tudo armado. Mas as instalações ainda não acabaram! Agora quem trabalha é o npm.

Algo bacana de observar é como a tecnologia se reinventa e segue sendo a mesma coisa; veja quantos anos separam o apt-get, o irmão mais velho, do npm, o caçula, sem falar das app stores, os irmãos ricos. Devaneios à parte, hora de instalar o pg, o knex, o bower e o express:
sudo npm -g install express knex pg bower

O -g serve para informar que a instalação é de escopo global (usando o sudo então ela torna-se a nível de sistema), o bower é um outro gerenciador de dependências, só que focado no lado do cliente e não do servidor, o pg é a biblioteca que permite o node conectar-se ao postgresql, o knex é um cara muito bacana, ele nos auxilia nas queries de banco e umas coisas a mais e o express é o roteador/controlador mais bacanudo que tem pro node!

Caso você não tenha costume de usar o npm, uma tela feia pra caramba feito esta quer dizer que deu certo:

Estamos indo bem. Vamos para as configurações agora.

Primeiro vamos configurar o banco de dados que instalamos:
sudo postgresql-setup initdb

Não terminamos ainda, vamos definir uma senha pro usuário do banco de dados:
sudo service postgresql start
sudo su
su postgres
psql
alter user postgres with password 'postgres'


Feito isso, podemos mudar o esquema de autenticação do banco para md5. Abra o arquvo /var/lib/pgsql/data/pg_hba.conf:
sudo vi /var/lib/pgsql/data/pg_hba.conf

As linhas finais do arquivo devem ficar mais ou menos assim:

Salve e reinicie o serviço de banco. crie o esquema com o comando createdb 
sudo createdb -U postgres -W -h localhost mymural

O -h localhost é pra forçar uma conexão via rede, o -W pra pedir senha, o -U postgres pra indicar o usuário e mymural é o nome que escolhi pro esquema de banco.

Deixemos o banco um pouco de lado e vamos criar nossa aplicação. no terminal vamos chamar o npm init e ir respondendo as perguntas:
mkdir mymuralcd mymuralnpm init

O npm cria o pacote e baixa as dependências também. e é justo isso que vamos fazer agora. Lembra das coisas que instalamos lá no começo? pois bem, agora iremos relacionar elas neste projeto:
npm install express knex pg --save

Após isso, uma pasta foi criada dentro da pasta do projeto: node_modules. o node baixa tudo o que você vai precisar dentro dessa pasta, e após isso você poderá usar os módulos.

Agora cuidaremos da conexão com o banco usando a ferramenta  knex (e foi por isso que instalamos ele globalmente):
knex init

Como precisaremos alterar algumas coisas no arquivo que o knex criou, hora de botar o atom pra trabalhar. A graça do atom é abrir uma pasta inteira. Abra o editor, e no menu File escolha a opção Add Project Folder:

Aponte para a pasta que criamos anteriormente:

Abra por fim o arquivo knexfile.js:

Neste arquivo temos várias opções distintas de configuração, para diferentes momentos do projeto. Como eu não vou muito longe nisso hoje, vamos corrigir apenas a configuração de desenvolvimento para apontar para o banco que criamos. após isso retorne ao console e crie o arquivo de migrations:
knex migrate:make esquema_inicial

O comando knex migrate:make esquema_inicial cria mais uma pasta e mais um arquivo no projeto. Usando o atom abra este arquivo e modifique-o para criar nossa tabela na função up e para destruir esta tabela na função down:

Deve ficar mais ou menos assim seu script de criação de tabela:
exports.up = function(knex, Promise) {
  return knex.schema.createTable('mensagem', function (table) {
    table.increments('idmensagem');
    table.string('email').unique();
    table.string('titulomensagem').notNullable();
    table.text('corpomensagem').notNullable();
    table.date('datamensagem').defaultTo(knex.raw('now()'));
  });
};

exports.down = function(knex, Promise) {
  return knex.schema.dropTable('mensagem');
};



Estamos no meio do caminho. Vamos criar nosso script de entrada, aquele que indicamos no npm init. Na pasta do projeto e pelo menu do Atom, crie um arquivo chamado index.js:

Nele vamos colocar algumas coisas. É onde vamos chamar os componentes para fazer este aplicativo servir de alguma coisa.

Vamos começar colocando em nosso script a estrutura básica do express: a biblioteca em si, uma chamada para listar mensagens de mural outra chamada para salvar uma nova mensagem, especificar o nome do diretório onde ficarão as coisas do lado do cliente e iniciar o servidor:

Agora crie o diretório public dentro da pasta do projeto e dentro dele crie o arquivo index.html:

De volta ao console agora. Vamos usar o bower para resolver as dependências de scripts para o lado do cliente.
cd publicbower init 

Caso não tenha ficado claro, o bower é para o lado web do aplicativo o que o npm é para o lado servidor do aplicativo.

Neste aplicativo específico, nossa única dependência será o angular. usando o bower, a instalação se resume ao seguinte:
bower install angular --save

Note a pasta criada: bower_components.

Voltemos ao nosso arquivo html façamos as modificações para que ele use o angular:

Agora que nosso markup está completo, podemos criar mais um script (mymural.js), este conterá o módulo mymural (data-ng-app) e o controller MyMural (data-ng-controller), indicados no index.html:

Código este que deve ficar assim:
// criando o módulo
angular.module("mymural",[]);
// adicionando um controlador ao módulo:
angular.module("mymural").controller("MyMural",function($scope,$http){
  // função pra dar um estado inicial para a tela
  $scope.initmural=function(){
    $scope.novamsg={
      titulomensagem:"",
      corpomensagem:""
    };
    $http({
      method : "GET",
      url : "mensagens",
      headers : {
       "Content-Type" : "application/json"
      }
    }).then(function(res){
      $scope.mensagens=res.data;
    });
  };
  // começar com a lista e com o formulário limpo
  $scope.initmural();
  // esta chamada salva no servidor uma nova mensagem
  $scope.enviamsg=function(){
    $http({
      method : "POST",
      url : "novamensagem",
      headers : {
        "Content-Type" : "application/json"
      },
      data:JSON.stringify($scope.novamsg)
    }).then(function(res){
      alert(res.data);
      $scope.initmural();
    });
  };
});

Atenção para a sutil diferença entre criar um módulo e chamar um módulo.

Na linha 2 criamos o módulo, pois a função module foi chamada com dois argumentos, sendo o segundo o array de dependências.

Na linha 4 apenas chamamos o módulo e nele penduramos um controller.

Isso é útil para fazer projetos maiores.

Voltemos para o lado do servidor. é hora de consultarmos e salvarmos os dados. Abra novamente o index.js (que está fora da pasta public, junto dos outros arquivos do servidor) e modifique-o para ficar assim:

Veja o código:
/* módulos que usaremos */
var express = require("express");
var bodyParser = require("body-parser");
var knexfile = require("./knexfile");
var knex = require("knex")(knexfile.development);
/* garantindo que temos a versão mais recente do banco */
knex.migrate.latest();
/* referência ao express */
var app = express();
/* biblioteca para enviarmos e recebermos JSON no corpo das requisições */
app.use(bodyParser.json());
// listar mensagens
app.get("/mensagens",function(req,res){
  knex("mensagem").select().then(function(result){
    res.json(result);
  });
});
// salvar nova mensagem
app.post("/novamensagem",function(req,res){
  var novamsg = req.body;
  knex("mensagem").insert(novamsg,"idmensagem").then(function(retid){
    res.send("Mensagem salva - id: "+retid);
  });
});
// diretório de arquivos estáticos (client side)
app.use(express.static("public"));
// iniciando o servidor
app.listen(3000);

Algumas considerações importantes: caso seu aplicativo cresça e você passe a organizar ele em módulos do node, o express você pode chamar sem maiores problemas em outros arquivos, mas o knex só pode ser chamado uma vez. Ele deverá ser passado por parâmetro para os módulos que precisem de acesso ao banco de dados.

A linha app.use(bodyParser.json()); serve pra dar capacidade de entender json ao express. é necessário instalar o módulo body-parser usando o npm:
cd ..npm install body-parser --save

E agora execute seu projeto. Pelo console, dentro da pasta do projeto, chame o node:
node index.js

Note que o prompt do console não voltou mais. É assim mesmo, tem ferramentas que gerenciam a execução dos seus projetos node, mas não vou falar delas aqui.

Vá para o navegador de internet e digite http://localhost:3000 no endereço e observe:

Como? O que falta agora?

Falta nada não, acabou o tutorial.

Bacana né?

Falando um pouco sobre este experimento em si, dá pra perceber como o node tem amadurecido.

Na hora de escolher uma plataforma pra trabalhar, eu considero hoje o node uma escolha segura, talvez não tão consolidada quanto o JEE, mas certamente mais elegante.

Considero o knex e a variante de migrations que ele usa uma surpresa à parte.

Aqui no blog tem outros aplicativos de natureza parecida, você pode dar uma conferida, comparar, enfim.

Outro ponto que vale apontar é que não foi preciso uma IDE peso-pesado, como o eclipse, para ser produtivo com esse kit de tecnologias apresentado. Uma reflexão poderia ser tecida, mas deixo as filosofias pra você meu caro leitor.

O código fonte desta postagem você encontra aqui.

Até a próxima.

Sem mais.






Nenhum comentário :

Postar um comentário