Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Node.js
Code

Introdução a Geradores & Koa.js: Parte 2

by
Difficulty:IntermediateLength:LongLanguages:
This post is part of a series called Introduction to Generators & Koa.js.
Introduction to Generators & Koa.js: Part 1

Portuguese (Português) translation by Erick Patrick (you can also view the original English article)

Final product image
What You'll Be Creating

Bem-vindo à segunda parte da nossa série sobre geradores e Koa. Se você perdeu a primeira parte, pode lê-la aqui. Antes de começarmos com o processo de desenvolvimento, tenha certeza de ter instalado a versão 0.11.9, ou mais recente, do Node.js.

Nesta parte, começaremos a criar nossa API usando o Koa.js e você aprenderá sobre roteamento, compressão, registros de log, limitação de uso e manipulação de erros no Koa.js. Também usaremos o Mongo como nosso armazenamento de dados e aprenderemos rapidamente sobre a importação de dados para o Mongo, e o quão fácil é selecionar dados usando o Koa. Finalmente, veremos como depurar apps no Koa.

Entendendo o Koa

Koa tem mudanças substanciais por trás dos panos, fazendo uso das maravilhas dos geradores do EcmaScript 6. Fora a mudança de fluxo de controle, o Koa introduz seus próprios objetos customizados, como o this, this.request e othis.response, que funcionam como uma camada de açúcar sintático sobre os objetos req e res do Node, dando-lhe acesso a vários métodos convenientes e vários getters/setters

Além das conveniências, o Koa também faz uma limpeza nos mediadores que, no Express, dependia de hacks horrorosos que quase sempre modificavam os objetos base. Também fornece uma melhor manipulação de fluxo de dados.

Espere, O Que É Um Mediador?

Um mediador é uma função plugável que adiciona ou remover alguma funcionalidade específica ao realizar alguma tarefa nos objetos de requisição/resposta do Node.js.

Mediadores do Koa

Essencialmente, um mediador do Koa é uma função geradora que retorna uma função geradora e que aceita uma outra função geradora. Geralmente, uma aplicação possui uma série de mediadores que são executados a cada requisição. 

Além disso, um mediador deve retornar para o próximo mediador abaixo no fluxo de controle, caso seja executado por um mediador mais alto. Discutiremos mais sobre isso na seção de manipulação de erros.

Construindo Mediadores

Uma última coisa: Para adicionar um mediador à sua aplicação Koa, usaremos o método koa.use() e prover uma função mediadora (geradora) como argumento. Exemplo: app.use(koa-logger) adiciona o koa-logger à lista de mediadores que nossa aplicação usa.

Construindo a Aplicação

Para começar com a API do dicionário, precisamos de conjunto funcional de definições. Para recriar esse cenário da vida real, decidimos ir com um conjunto de dados real. Baixamos a lista de definições da Wikipedia e carregamos no Mongo. O conjunto tem cerca de 700.000 palavras, uma vez que importamos somente a lista de definições em inglês. Cada registro (ou documento) consiste de uma palavra, seu tipo e seu significado. Você pode ler mais sobre o processo de importação no arquivo import.txt do repositório.

Continuando com o processo de desenvolvimento, clone o repositório e verifique seu progresso, navegando pelos diferentes commits. Para clonar o repositório, use o comando a seguir:

Comecemos criando um servidor base do Koa:

Na primeira linha, importamos o Koa e salvamos uma instância na variável app. Então, adicionamos um único mediador na linha 5, que é uma função geradora anônima que recebe a variável next como parâmetro. Aqui, atribuímos o tipo e o estado da resposta, que é determinado automaticamente, mas também podemos configurá-lo manualmente. Finalmente, configuramos o corpo da resposta. 

Já que configuramos o corpo de nosso primeiro mediador, ele marcará o fim de cada ciclo de requisição e não envolveremos qualquer outro mediador. Por último, iniciamos o servidor, executando seu método listen e passando um número de porta como parâmetro.

Podemos iniciar o servidor através da execução do script, dessa forma:

Você pode ir direto para esse ponto, buscando o commit 6858ae0:

Adicionando Capacidade de Roteamento

Roteamento permite-nos redirecionar diferentes requisições a diferentes funções, baseado no tipo da requisição e na URL requisitada. Por exemplo, podemos querer responder a /login diferentemente de signup. Isso pode ser feito a partir da adição de um mediador, que verifica manualmente a URL da requisição recebida e executa as funções correspondentes. Ou, ao invés de escrever o mediador manualmente, podemos usar um mediador criado pela comunidade, também conhecido como módulo mediador.

Para adicionar a capacidade de roteamento à nossa aplicação, usaremos um módulo da comunidade chamado de koa-router

Para usar o koa-router, modificaremos o código que já temos para algo parecido com isso:

Nós importamos dois módulos aqui, onde a variável router guarda o koa-router e a variável mount guarda o módulo koa-mount, permitindo-nos usar o roteador em nossa aplicação Koa.

Na linha 6, definimos nossa função handler, que é a mesma função de antes mas, dessa vez, demos um nome a ela. Na linha 12, guardamos uma instância do roteador em APIv1 e na linha 13 registrarmos nosso manipulador para requisições GET na rota /all

Assim, todas as requisições retornarão "not found", exceto aquelas que foram feitas para localhost:3000/all. Finalmente, na linha 15, usamos o mediador mount, que nos fornece uma função gerador que pode ser passada para app.use().

Para ver esse passo em específico ou comparar sua aplicação, execute o seguinte comando no repositório clonado:

Antes de executarmos nossa aplicação, precisamos instalar o koa-router e o koa-mount usando o npm. De acordo com o aumento da complexidade da aplicação, o número de módulos/dependências também aumenta. 

Para manter o controle de todas as informações relacionadas ao projeto e disponibilizar esses dados no npm, guardamos toda a informação em um arquivo package.json, incluindo todas as dependências. Você pode criar um arquivo package.json manualmente ou usar a interface interativa de linha de comando, que abrimos com o comando $ npm init .

Um arquivo package.json bem simples deve ser parecido com o que temos acima. 

Uma vez que o arquivo package.json esteja presente, você pode salvar a dependência usando o comando a seguir:

Por exemplo: Nesse caso, instalaremos os módulos usando o comando abaixo e registraremos as dependências no arquivo package.json.

Agora, você pode executar sua aplicação, usando $ node --harmony index.js

Você pode ler mais sobre o arquivo package.json aqui.

Adicionando Rotas para a API do Dicionário

Começaremos criando duas rotas para a API, uma para obter todos os resultados em uma consulta rápida e uma segunda para obter todas as palavras combinantes (que é bem mais devagar na primeira vez). 

Para manter controle sobre as coisas, colocaremos as funções da API em um diretório à parte, chamado de api e em um arquivo api.js, e importaremos esse último em nosso arquivo index.js posteriormente.

Aqui, usaremos o co-monk, que age como um invólucro para o monk, facilitando bastante o nosso trabalho de consultar o MongoDB usando geradores no Koa. Aqui, nós importamos o monk e co-monk, e conectamos à instância do MongoDB na linha 3. Invocamos o método wrap() nas coleções, para torná-lo amigável a geradores. 

Logo depois adicionamos dois métodos geradores, chamados all e single, como propriedades da variável exports, de modo que eles possam ser importados por outros arquivos. Em cada uma dessas funções, primeiro verificamos o parâmetro da consulta, word. Se ele estiver presente, realizamos a consulta e a retornamos. Caso contrário, lançamos um erro 404. 

Usamos a palavra-chave yield para esperar pelos resultados, assim como foi discutido no primeiro artigo, pausando a execução daquela função até que o resultado seja recebido. Na linha 12, usamos o método find, que retorna todas as palavras combinantes, que são salvar em res e, subsequentemente, enviadas de volta. Na linha 23, usamos o método findOne disponível na coleção, que retorna o primeiro resultado combinante. 

Atribuindo Os Manipuladores às Rotas

Aqui importamos os métodos exportados do arquivo api.js e atribuímos os manipuladores às respectivas rotas GET, /all/single, e temos uma API completamente funcional e aplicação pronta, agora.

Para executar a aplicação, você só precisa instalar os módulos monk e co-monk usando o comando abaixo. Além disso, garanta a existência de uma instância do MongoDB executando, a qual você importou os dados, de acordo com as instruções mencionadas no arquivo import.txt, presente no repositório do GitHub.

Agora, execute a aplicação usando o comando a seguir:

Você pode abrir o navegador e abrir as seguintes URLS para verificar o funcionamento da aplicação. Apenas substitua a palavra 'new' por uma outra palavra que queira consultar.

  • http://localhost:3000/v1/all?word=new
  • http://localhost:3000/v1/single?word=new

Para chegar a esse passo rapidamente, execute o comando a seguir no diretório do repositório clonado:

Manipulação de Erros no Koa

Ao usar mediadores em cascata, podemos capturar erros usando o mecanismo try/catch, uma vez que cada mediador pode responder enquanto repassa para os geradores abaixo e acima. Assim, se adicionarmos um mediador Try and Catch no começo da aplicação, ele capturará todos os erros encontrados pela requisição durante a passagem por todos os outros mediadores, uma vez que ele será o último mediador na volta dos geradores. Para tanto, basta adicionar o código a seguir na linha 10 do arquivo index.js ou antes.

Adicionando Registro de Log e Limitação de Uso na Aplicação

Registrar logs é uma parte essencial de uma aplicação moderna, uma vez que são bastante úteis na depuração e descoberta de problemas em nossas aplicações. Eles também guardam todas as atividades realizada e, dessa forma, podem ser usados para descobrir padrões de atividade de usuários e outros padrões interessantes. 

Limitação de uso também se tornou uma parte essencial de aplicações modernos, onde é importante parar spammers e bots de drenarem recursos preciosos do servidor e pará-los de consumir sua API.

É bem simples de adicionar registro de logs e limitação de uso em uma aplicação Koa. Usaremos dois módulos da comunidade: koa-logger ekoa-better-rate-limiting. Precisamos adicionar o código a seguir à nossa aplicação:

Nessa parte, importamos os dois módulos e os adicionamos como mediador. O registrador de logs salvará e imprimirá na stdout do processo que pode ser salva, facilmente em um arquivo. E o limitador de uso limita o número de requisições que um dado usuário pode fazer em um determinado período de tempo (o máximo de requisições aqui é de 10 em 3 minutos). Você também pode adicionar um vetor de endereços IP que pode ser bloqueadas e suas requisições não serão processadas.

Lembre-se de instalar os móduos antes de usá-los, usando o comando abaixo: 

Comprimindo o Tráfego

Uma das maneiras de garantir uma entrega rápida é usar gzip em sua resposta, que é bem simples no Koa. Para comprimir o tráfego no koa, você pode usar o módulo koa-compress

Nesse caso, as opções podem ser um objeto vazio ou podem ser configurados de acordo com a necessidade.

Você pode até desligar a compressão em uma requisição adicionando o trecho de código a seguir ao mediador:

Não esqueça de instalar o módulo compress através do npm

Para chegar a esse estágio e comparar à sua aplicação, execute o comando a seguir no diretório do repositório clonado:

Escrevendo Testes

Testes devem ser uma parte essencial de qualquer código e devem objetivar o máximo de cobertura do código que for possível. Nesse artigo, criaremos os testes paras as rotas que são acessíveis em nossa aplicação. Usaremos o supertest e o Mocha para criar nossos testes. 

Salvaremos nossos testes no arquivo test.js que ficará dentro da pasta api. Em ambos os casos, primeiro descreveremos nosso teste, dando-lhe um nome mais legível por humanos. Logo depois, passaremos uma função anônima que descreverá o comportamento correto do teste e levará uma função callback que conterá o teste de verdade. Em cada teste, importaremos nossa aplicação, iniciaremos o servidor, descreveremos o tipo de requisição, URL e consulta, e então passaremos a codificação para o gzip. Finalmente, verificaremos se a resposta está correta.

Para executar nosso teste, criaremos um arquivo Makefile:

Nós configuramos o relator (nyan cat) e o framework de testes (mocha). Perceba que a importação deve adicionar o semáforo --harmony para habilitar o modo ES6. Finalmente, também especificamos o local onde estão os testes. Um arquivo Makefile configurado para testes infinitos da sua aplicação.

Agora, para testar sua aplicação, apenas execute o comando a seguir, no diretório principal da sua aplicação. 

Lembre-se de instalar os módulos de teste (mocha, should, supertest) antes de executar os testes, usando o comando abaixo: 

Executando em Modo Produção

Para executar nossa aplicação em produção, usaremos o PM2, que é um monitor de processo para Node, muito útil. Nós devemos desabilitar o registrador de logs na produção. Isso pode ser automatizado através de variáveis de ambiente.

Para instalar o PM2, digite o comando a seguir no terminal

E nosso aplicativo pode ser iniciado, usando o comando a seguir:

Agora, mesmo que nossa aplicação dê problemas, ela reiniciará automaticamente e você pode dormir sem problemas. 

Conclusão

O Koa é um mediador leve e expressivo para o Node.js que torna o processo de criação de aplicações web e de APIs muito mais agradáveis. 

Ele permite você lançar mão de uma enorme gama de módulos da comunidade para estender a funcionalidade de sua aplicação e simplificar as tarefas padrões, tornando o desenvolvimento para web uma atividade divertida. 

Por favor, não hesite em deixar comentários, perguntas ou quaisquer outras informações logo abaixo.

Seja o primeiro a saber sobre novas traduções–siga @tutsplus_pt no Twitter!

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.