tw-recife



tw-recife

0 2


tw-recife

thoughtworks recife presentation

On Github BackshopCollege / tw-recife

" Once a new TECHNOLOGY starts rolling, if you're not part of the steamroller, you're part of the road. " Stewart Brand

Um dia no Node JS

About me

Thiago Dantas

github.com/tdantas twitter.com/thiagochapa yld.io/team/thiago+dantas

About you

Linguagens de Programação ? Web Development familiarizado ? Experiência em Node ?

RECAP.JS

Qual o output e por quê?

var name = 'https://www.yld.io';

function greetings() {
  if (!name) {
    var name = 'http://www.thoughtworks.com';
  }

  console.log(name);
}

greetings();

Qual o output e por quê?

function sayMyName() {
  iAm();
  return;

  function iAm() {
    console.log('thiago dantas');  
  }
}

sayMyName();

Qual o output e por quê?

function whereAmIFrom() {
  city();
  country();

  var country = function() {
    console.log('Eu sou Brasileiro, entretanto vivo em Portugal');
  };

  function city() {
    console.log('Vivia em Recife e agora vivo em Lisboa');
  }
}

whereAmIFrom();

Timers

function setTimeout(fn, ms) {}  

function sayHello() {
 console.log('hello');
}

setTimeout(sayHello, 1000);

Qual o valor de sharedVariable ?

var sharedVariable = 0;

function inc() {
  sharedVariable = sharedVariable + 1;
}

var loop = 100;
while(loop--) 
  var t1 = setTimeout(inc, 1000);

var t2 = setTimeout(function(){
  console.log(sharedVariable); 
}, 5000);

Qual o output ?

function slow() {
  var start = Date.now();
  while (Date.now() < start + 3e3);

  console.log('slow');
}

function fast() {
  console.log('fast');
}

setTimeout(slow, 1000);
setTimeout(fast, 1000);

Homework

function square(number) {
  setTimeout(function() {
    return number * number;
  }, Math.floor(Math.random() * 100));
}

var numbers = [ 1, 2, 3, 4, 5 ];

map(numbers, square, function(err, result) {
  if (err)
    return console.error('Failed ', err);

  console.log(result); // [ 1, 4, 9, 16, 25 ]
});

Agenda

Manhã

  • Nodejs Intro
  • NodeSchool

Agenda

Tarde

  • HapiJS
  • Questões / Dúvidas

Introdução

Antes de iniciarmos, acredito que para termos um maior proveito de hoje, vamos tentar ao maximo fazer/sentir como as coisas funcionam ao inves de estarmos o dia todo sentado e assistindo. Ok ?

Instalação

Node JSDocumentação

Version Manager

NVMN

O que é o Node.Js ?

Javascript no lado do Servidor

Node allows you to build scalable network applications using JavaScript on the server-side.

JavaScript: V8 Javascript engine

Cross-platforma: libuv

Modelo Síncrono vs Assíncrono

Síncrono

Ruby / Java / Python ....

Síncrono

userId = 293;
user = User.by(userId); // 100ms
 // WAITING ....
Mailer.welcome(user);
puts 'Email Sent'

Síncrono

Como atender múltiplas requisições em simultâneo ?

Threads / Processos

Assíncrono

Transformar de Sync para Async

function getRemoteUser(id) {
  var user = {
    id: id,
    name: 'thiago'
  };

  return user;
}

function printUser(user) {
 console.log(user);
}

var user = getRemoteUser(100);
printUser(user);

o mundo visto assincronamente

var userId = 239;
User.by(userId, function(err, user) {
  if (err)
    return console.error(err);

  Mailer.welcome(user, console.log);
});

console.log('Email Sent');
- Numa função asincrona ( AJAX por exemplo ) como recuperamos o valor da chamada ? No sincrono sabemos que o 'return' faz este papel.

Event-Loop

Metáfora Event Loop

Fluxo de Trabalho

  • Cliente chega ao restaurante e senta em uma mesa.
  • O Garçom atende apenas um cliente por vez.
  • O Garçom recolhe o pedido e leva o pedido a cozinha.
  • Quando o Pedido está pronto, a cozinha toca o sino.
  • Quando o Garçom estiver livre, pega o pedido e leva a respectiva mesa.

Pseudo-código

 while(queue.waitForMessage()) {
    queue.processNextMessage();
 }

Let's

  • repl
  • command line arguments
  • ler um ficheiro
  • http basic server
  • criando um módulo
  • downloading módulos externos ( npm )
    • install
    • criando package.json ( init )
    • install versão especifica
    • install github
    • install dev dependencies

Homework

  $ npm install -g learnyounode
  $ learnyounode

Quem utiliza o Hapi.JS ?

...

agenda

Hands On

  • Rotas
  • Validação/Contrato endpoint
  • Caching
  • Tests
  • Exercícios

Rotas

$ mkdir web
$ cd web
$ npm init .
$ <YOUR_EDITOR> index.js

Uma Rota de boas-vindas

var Hapi = require('hapi');
var server = new Hapi.Server();
server.connection({ port: 3000 });

server.route({
  method: 'GET',
  path: '/ola',
  handler: function(request, reply) {
    reply('oi'); 
  }
});

server.start(function() {
  console.log('Server Started', server.info.port);
});

Custom Header, Status Code and Content-Type

 ...
server.route({
method: 'GET',
path: '/',
handler: function(request, reply) {

var response = reply('Welcome');


response.code(201);

response.header('kf-track-token', 'track-12839948');

response.type('application/json');
}
});
 ...

Capturing Query String

...
server.route({
  method: 'GET',
  path: '/search',
  handler: function(request, reply) {
    var query = request.query;
    var q = query.q;

    if (!q) 
      return reply([]);

    return reply([q]);
  }
});
...

http://api.your-domain.com.br/users/179/show

http://api.your-domain.com.br/users/179/show

Capturando paramentros da rota

...

function showUser(request, reply) {
  var params = request.params;
  var userId = params.userId;

  reply(userId);
}

server.route({
  method: 'GET',
  path: '/users/{userId}',
  handler: showUser
});

...

Regra de Negócio

O Gestor do produto diz: Eu quero ser capaz de criar usuários utilizando a api web.

SPEC

   request:
    path: '/users'
    method: POST
    content-type: application/json
    payload: { name: <name> }
     - name is required *

   response:
    invalid payload: 
      status code: 400
      content-type: application/json
      payload: < error message >

    invalid content-type
      status code: 415
      content-type application/json

    success:
     status code: 201
     content-type: application/json
     payload: 
      { name: <name> , id: <id> }

Solução

server.route({   
  method: 'POST',   
  path: '/users',   
  handler: function(request, reply) {   
     var contentType = request.headers['content-type'];  
     if (contentType !== 'application/json')   
      return reply().code(415).type('application/json');   

    var payload = request.payload;    
    if (!payload.name)   
      return reply('Name is required').code(400).type('application/json');   

    var id = Date.now();   
    var user = { name: payload.name, id: id };   

    reply(user).code(201);   
  }
});

Solução II

function createUser(request, reply) {
  var payload = request.payload;
  var id = Date.now();
  var user = { name: payload.name, id: id };
  reply(user).code(201);
}

server.route({
  method: 'POST',
  path: '/users',
  handler: createUser,
  config: {
    payload: {
      allow: [ 'application/json' ]
    },
    validate: {
      payload: {
        name: Joi.string().required()
      }
    }
  }
});

Server Methods

Um excelente candidato para colocarmos nossas regras de negócio com o poder da cache

Tests

Helpers

var Lab = require('lab');var assert = require('chai').assert;var lab = exports.lab = Lab.script(); var describe = lab.describe;var it = lab.it;var before = lab.before;var after = lab.after;var beforeEach = lab.beforeEach;server.inject({ method: 'POST', url: '/url', payload: { name: 'thiago' }, headers: { 'x-custom': 'thiago' } }), verify);

Onde posso aprender mais ?

Node Patterns Bundle

Na Interwebs :)

Awesome Node.JSYLD! BlogRequireLXJavascript WeeklyNode Weekly

Obrigado

Venham nos visitar em Lisboa e Londres

Para mais treinamento: training@yld.io

" Once a new TECHNOLOGY starts rolling, if you're not part of the steamroller, you're part of the road. " Stewart Brand