Introdução prática ao AdonisJS: Criando um APP de eventos

 

Bem vindo programador(a)!

Nesse primeiro artigo que resolvi me aventurar em NodeJS, vou falar pra você um pouco sobre o AdonisJS, um framework MVC que utiliza Convenção sobre Configuração (CoC – Convention over Configuration) para facilitar a nossa vida :]

E pra quem não sabe, Convenção sobre Configuração é uma técnica que facilita o desenvolvimento ao diminuir o número de decisões triviais que precisamos tomar através do uso de configurações padrões, deixando apenas as decisões importantes para nós.

Vamos entender melhor no decorrer do código.

 

Ferramentas que utilizaremos

  • AdonisJS 4.1
  • SQLite
  • Yarn
  • Bulma

 

Resumo do projeto

Neste artigo vamos desenvolver um APP de eventos onde é possível que um usuário cadastre um determinado evento público (com título, data e descrição) e que outros usuários marquem se vão ao evento permitindo uma contagem de quantidade de pessoas.

Então teremos as funcionalidades:

  • Cadastrar um evento
  • Editar um evento
  • Remover um evento
  • Marcar “Eu vou”

Então prepara o relógio, pegue o café e bora!

 

Começando a codar!

 

1. Instalando o AdonisJS

Neste artigo vamos utilizar o Yarn (você pode usar o npm se desejar), então pra quem não tem o Yarn, só ir neste link das docs e instalar:
https://yarnpkg.com/en/docs/install

 

A – Primeiro, vamos executar o seguite comando do Yarn para instalar o AdonisJS:

Estamos executando o comando com o sudo porque estamos instalando a CLI do Adonis globalmente

 

B – Caso queira verificar a versão

Caso opter por ver a versão, ela vai aparecer a versão o Adonis CLI. A versão do AdonisJS veremos assim que criamos o projeto

 

 

2. App de eventos

Nesta parte vamos ao coração do post, onde desenvolveremos nosso APP de eventos. Repare que todos as partes a seguir onde tivermos códigos, eu colocarei o nome da branch do repositório para que você possa ver o que eu fiz passo a passo no código :]

 

2.1 Iniciando o projeto

A – Para iniciar o projeto, vamos executar o seguinte comando:

Estamos iniciando um novo projeto com o nome public_events e passando a opção –yarn para utilizarmos o Yarn como gerenciador de pacotes padrão deste projeto

 

B – Agora vamos entrar no diretório da aplicação:

 

C – E vamos executar o seguinte comando para iniciar o servidor de desenvolvimento do Adonis:

Repare que, por padrão, o Adonis inicia o servidor na porta 3333

 

D – Depois de iniciar o servidor, abra o seu navegador na url http://127.0.0.1:3333 para ver a página de boas vindas do Adonis, que será como esta

 

2.2 Diretórios do Adonis

Vamos explicar brevemente os diretórios que o Adonis tem:

  • /app

Onde estão as estruturas do nosso app, como os Middlewares, Controllers e Models. Mais pra frente veremos cada um deles : )

Perceba que inicialmente há somente Middlewares e Models. Conforme formos criando as estruturas, as outras pastas vão surgindo.

  • /config

Onde armazenamos as configurações da aplicação. Por exemplo, o arquivo database.js vem com as configurações de conexão ao banco de dados conforme o tipo de banco que utilizaremos.

  • /database/migrations

Nesta pasta ficarão as migrations, que são estrutura que fazem operações de DDL.

  • public

Aqui armazenaremos os nosso assets como CSS, JS do frontend e imagens

  • resources

Aqui armazenaremos os recursos de telas como views e layouts

  • start

Aqui estão os arquivos que basicamente registrarão os middlewares que nosso app utiliza e o arquivo de rotas, onde vamos definir as rotas que nosso APP terá juntamente com o controller para o qual será direcionado.

 

2.3 Fazendo a primeira view

[Branch: first_view]

Como dissemos anteriormente, vamos focar apenas no Adonis neste post, então não vamos utilizar empacotadores como webpack ou bower. Utilizaremos o CDN do Bulma e colocaremos todos os nossos assets direto na pasta public, que justamente onde o Adonis busca pelos assets.

Para o frontend, o Adonis utiliza uma ferramenta de template chamada Edge, Vamos entender um pouco como ele funciona nos códigos.

 

A – Primeiro, vamos criar um diretório resources/layouts e dentro dele o arquivo main.edge

 

B – E acrescente o seguinte conteúdo em resources/views/layouts/main.edge

O que estamos fazendo aqui é basicamente criando um template que utilizaremos em todas as nossas páginas e neste template importando o Bulma e o FontAwesome via CDN
Repare no conteúdo @!section(‘content’), ele é uma notação do Edge. É através dessa notação que vamos conseguir embutir os códigos das nossas views dentro desse template. Não se preocupe, já chegaremos lá

 

C – Agora vamos criar o diretório resources/views/home e dentro dele o arquivo resources/views/home/index.edge

 

D – E adicione o seguinte conteúdo em resources/views/home/index.edge

Olha que interessante: primeiro chamamos o @layout('layouts.main') justamente para informar que esta página home/index.edge deve usar o layout que criamos anteriormente; depois, criamos um bloco com @section('content') e @endsession que é um recurso que vai colocar tudo que estiver dentro deste bloco que tem nome content na declaração @!section('content') que fizemos lá em layouts/main.edge

 

E – Agora, por ultimo, vamos adicionar uma rota pra essa view. Vamos substituir a seguinte linha em start/routes.js

Por:

Estamos informando que, na rota / (rota raiz) ele deve renderizar a view home/index.edge

 

F – Se formos até o navegador, teremos:

 

 

2.4 Primeiro controller

[Branch: first_controller]

A – Para começar, vamos executar o seguinte comando para criarmos um controller chamado EventsController

 

B – Na execução deste comando, ele vai mostrar uma lista para escolhermos tipo de controller queremos criar. A lista vai aparecer deste jeito:

Vamos selecionar a opção For HTTP requests

O Adonis nos proporciona uma CLI para que possamos criar um controller já num padrão de diretórios e mais legal ainda, ele nos pergunta que tipo que controller queremos.

Isso se deve ao fato do Adonis também ter suporte para conexões Websocket. Pra quem nunca ouviu falar, é um protocolo que roda em cima HTTP que permite que a troca de mensagens entre cliente e servidor seja feita sem a necessidade de requisição.

Por hora, já que estamos falando do básico do Adonis, vamos ficar no HTTP ^^

Repare que foi criado um diretório app/Controllers/Http com um arquivo EventController.js. Vamos trabalhar nele agora

 

C – Acrescente o seguinte código em app/Controllers/Http/EventController.js

Repare que adicionamos a primeira action do controller chamada index. Toda action recebe um parâmetro que contém as propriedados que nos auxiliam com a requisição e a resposta.

Observe que chamamos a propriodade view deste objeto que utitlizamos para renderizar uma view event.index. Ao ler isso, ele vai buscar pelo aquido event/index.edge dentro de resouces/views (já vamos criar)

 

D – Vamos aproveitar a desconstrução de objetos do Javascript e refatorar esse controller

Utilizando a descontrução de objetos, pegamos apenas a propriodade view do antigo objeto ctx, que é a que nos interessa neste momento

 

E – Agora vamos criar uma view pra este controller

Utilizamos o comando do Adonis para criar a view event/index.edge e passamos uma opção --layout para que já acrescente a marcação @layout pra gente

 

F – Deixe a view resources/views/event/index.edge com o seguinte conteúdo

 

G – Adicione a seguinte rota em start/routes.js

Nesta rota estamos definindo a chamada GET a /events deve ser direcionada para o controller EventController na action index

 

H – Se abrirmos o navegador e formos até a url /events veremos a view que criamos.

 

 

 

2.5 Customizando o layout main e adicionando uma rota nomeada

[Branch: customize_main_layout]

Nesta parte vamos apenas adicionar um estilo ao nosso layout main com o Bulma e uma rota nomeada. Aqui vou evitar entrar em detalhes sobre o CSS do Bulma pra que a gente possa focar no aprendizado do Adonis.

 

A – No arquivo de rotas em start/routes.js substitua a linha abaixo

Por

Perceba que apenas adicionamos o método as. Com ele, nós conseguimos dar um nome único pra nossa rota. Já vamos ver pra que serve : )

 

B – No layout main em resources/views/layouts/main.edge, substitua o conteúdo atual por:

Adicionamos um menu superior com links para Home e Meus eventos e uma logo pro nosso app

Se atente para a linha 26 no main.edge que acabamos de atualizar:

Perceba que a propriedade href possui {{ route('events.index') }}.

As chaves duplas é o que o Edge utiliza para processar algum código no momento da renderização da view. O método
route é um helper que retorna uma URL com base no parâmetro que passamos e perceba que passamos como parâmetro o mesmo valor que definimos no método as nas rotas.

 

D – Se formos no navegador novamente, veremos que agora temos um menu e conseguimos navegar entre as páginas Home e Meus eventos

 

2.6 Criando um Model

[Branch: model_database]

Nesta parte vamos criar nosso primeiro Model, o Event. É com ele que vamos fazer as operações nos bancos de dados (caso queira pesquisar na documentação do Adonis, o model é possivel graças a uma ferramenta chamada Lucid.)

Antes de criamos o model, vamos instalar um plugin do SQLite3 para que o Adonis possa utilizar na conexão com o banco

 

A – Execute o comando

Com este comando ele já instala o plugin e configura

A configuração para a utilização do SQLite3 está no arquivo config/database.js na linha

Esta variável de ambiente DB_CONNECTION está dentro no nosso arquivo .env, na raiz do projeto, que o Adonis já carrega por padrão.

 

B – Com o banco configurado, vamos criar o model Event com o comando:

Repare que ele criou o arquivo app/Models/Event. Dentro deste diretório existem mais dois models, o User e o Token, mas podem ignorar por hora, falaremos deles mais tarde

 

Todo model Lucid se relaciona com uma tabela do banco de dados, então precisamos também criar uma migration pra isso. Uma migration é um trecho de código que realiza operações no banco, neste caso, vamos crirar uma tabela chamada events.

C – Para criar a migration, execute:

 

D – Ao digitar o comando, apareceção estas opções:

Vamos selecionar a opção Create table, já que queremos criar a tabela events

 

E – Perceba que foi criado o arquivo database/migrations/<timestamp>_events_schema.js. Este é o arquivo será executado para a criação de uma tabela no banco. Substitua o conteúdo deste arquivo por:

Perceba que ele tem um método up e um down. O up é executado quando informamos que a migration deve ser processada e o down quando ela deve ser regredida. No up, chamamos uma função create que recebe o nome da tabela e uma arrow function onde colocaremos os campos que queremos na tabela, no caso nas linhas 10, 11 e 12 criaremos os campos title, date e description como string, datetime e string.

A função
increments cria uma chave primária incremental e a timestamps cria um campo created_at para a data de criação e updated_at para a ultima atualização.

No método
down a tabela será apagada.

 

F – Agora vamose rodar esta migration executando:

Executa todas as migrations pendentes

 

Uma observação final: perceba que criamos o model Event e a tabela events no banco e que não fizemos nenhuma configuração pra isso. O que ocorre é que o Lucid opera com uma técnica chamada Convention Over Configuration, ou seja, já assume algumas convenções padrões para que não perdermos tempo com configurações básicas. No caso o Model, já é feito a busca de uma tabela que tenha o mesmo nome do model, mas no plural. Ou seja, o model Event já mapeia a tabela events do banco.

 

 

2.7 Formulário de criação do Evento

[Branch: create_event]

Para o formulário, utilizaremos um recurso do próprio Adonis.

 

A – Primeiro, vamos criar uma rota para a página create e uma outra rota que uilizaremos para processar o formulário de criação. Adicione em start/routes.js

Criamos uma rota GET /events/create que vai chamar a action create no controller EventController e carregar a view event/create que criaremos mais pra frente e uma outra rota POST /events que vai chamar a action store no mesmo controller que utilizaremos para processar o formulário que ficará na view event/create

 

B – Adicione o seguinte método em app/Controllers/Http/EventController.js

O método está renderizando uma view create. Vamos criá-la.

 

C – Execute o comando para criamos a view event/create

 

D – E acrescente o seguinte conteúdo na view resources/views/event/create

É um formulário HTML normal, com helpers do Adonis, como o route, que já vismos e a chamada ao csrfFields(), que acrescenta campos de chave para processar o formulário evitando ataques CSRF.

 

E – Após o formulário, atualize o EventController em app/Controllers/Http/EventController.js para o seguinte:

Primero importamos o model Event.

Em seguida, atualizamos a action
index para carregar todos os eventos e renderizar a view events.index passando a variável events como parâmetro. Nesta renderização, estamos utilizando um toJSON() para que o objeto vá serializado para a view.

Também criamos o método
store para salvar o Evento e redirecionar para a lista de eventos

 

F – Agora vamos atualizar a view index de eventos para listar os eventos cadastrados. Atualize o código de resources/views/events/index.edge para

Adicionamos na view um botão Novo Evento para irmos para formulário de criação do evento. Juntamente com isso, adicionamos um bloco @if do Edge para verificar se existe algum evento e caso não exista (bloco @else) ele mostrará uma mensagem.

Se existir algum evento na lista, utilizamos o bloco
@each para percorrer cada evento na lista e exibir. Perceba que utilizamos a notação {{ event.<propridade> }} do Edge para mostrar o valor na view.

 

 

2.8 Editar Evento

[Branch: edit_event]

Para editar o evento, vamos utilizar components, uma técnica de dividir trechos de uma view em partes menores e possibilitar o reuso.

 

A – Primeiro, vamos criar uma rota para exibir a view de editar e outra para submetermos o formulário de atualização. Vamos adicionar o seguinte em start/routes.js

Criamos uma nova /events/:id/edit e outra /events/:id. Esse :id é um recurso das rotas do Adonis para que ela seja considerada um parâmetro da rota. Então, por exemplo, se chamarmos a rota /events/1/edit o Adonis vai cair nesta rota /events/:id/edit e nos parâmetros será enviado um campo id com valor 1.

 

B – Próximo passo é criamos as actions em nosso EventController. Então vamos adicionar em app/Controllers/Http/EventController.js os métodos edit e update abaixo:

No edit, estamos utilizando o params, que também vem no método e nele está o parâmetro que passamos via URL. Estamos utilizando o id que esta lá para carregarmos o nosso evento com o método find e passamos como parâmetro da renderização da view event.edit, que criaremos mais pra frente.

No
update estamos carregando o evento da mesma forma que em edit, pegando os parâmetros do formulário, fazendo um merge com os atributos do evento que carregando (dessa forma ele altera do que estiver diferente no objeto event) e chamando o método save (que processa do banco de dados). Após salvar, redicionamos de volta pra lista de eventos.

 

C – Vamos agora criar noss componente. Pra isso, criaremos uma view form para o formulário de evento com o comando

 

D – E mover o formulário da view resources/views/event/create para resorces/views/event/form com algumas alterações. Inclua o seguinte conteúdo na view resources/views/edit/form:

Perceba que o atributo action do form agora possui uma chamada a action e method. Estas duas variáveis serão declaradas quando chamarmos o component mais pra frente. A variável action precisará receber a rota em que o form será enviado e a method, o tipo de método HTTP que será enviado. O que fizemos neste formulário com _method=... é uma técnica chamada de Method Spoofing. Isso ocorre porque os formulários HTML são capazes apenas de ligar com requisições GET e POST, então o Adonis aceita o parâmetro _method como o método que queremos chamar para a rota.

Outras duas variáveis importantes são a
csrfFields, que utilizamos para enviar os campos de CSRF do formulário e a event, onde enviaremos o evento. Perceba que nos campos estamos atribuindo o valor de uma propriedade do evento ou vazio. Estamos fazendo isso porque este formulário será utilizando tanto pra view create quando para a edit e na create, o evento ainda não existe, portanto event retorna undefined.

 

E – Próximo passo agora é atualizar a view resources/views/event/create.edge para

Perceba que estamos chamando o componente event.form que criamos anteriormente com @!component e passando os parâmetros que utilizamos neste componente.

 

F – E vamos também criar a view event.edit

 

G – E acrescentar o seguinte conteúdo em resources/view/event/edit.edge

Perceba que é semelhate à view de create, porém tem o título diferente e estamos passando a rota de update, com o verbo HTTP patch.

 

H – Vamos também atualizar a view resources/views/event/index.edge para acrescentar um botão de Editar em cada Evento listado. Atualize o código para

 

 

2.9 Remover evento

[Branch: remove_event]

A – Para remover o evento, primeiro vamos criar a rota para acessar. Adicione em start/routes.js

 

B – Agora vamos para a action para excluir no controller de Eventos. Adicione em app/Controllers/Http/EventController.js. Adicione a action destroy da seguinte forma

 

C – Após isso, vamos adicionar um botão de excluir na lista de eventos em resources/views/event/index.edge. Atualize a view para

Para evitar, por agora, mexer em reucrsos de frond-end para fazer o Method Spoofing fora de um formulário, criamos um mini formulário dentro de cada linha do evento que vai conter apenas o botão para ir para a página de edit e outro botão para remover que faz o submit do formulário que possui um Method spoofing com o verbo HTTP DELETE.

 

 

2.10 Marcar ‘Eu vou’

[Branch: people_count]

Agora, a última parte é adicionarmos os eventos na página Home para que possam clicar em “Eu vou” e aumentar a contagem de pessoas.

 

A – Antes de tudo, precisamos adicionar um campo de contagem na tabela de eventos e vamos fazer isso criando uma migration com o comando:

 

B – Vamos deixar a migration database/migrations/<timestamp>_events_schema.js que foi criada com o seguinte conteúdo

 

C – Agora vamos executar esta migration com o comando

 

D – Agora vamos criar um controller HTTP chamado PresenceController que utilizaremos contar mais uma pessoa no Evento. Execute o comando:

Não esqueça de selecionar a opção HTTP Controller

 

E – E adicione o seguinte conteúdo em app/Controllers/Http/PresenceController.js

 

F – Agora vamos adicionar mais uma rota em start/routes.js

 

H – Com o controller de presença pronto, vamos criar também um para a página Home. Execute:

Não esqueça de selecionar a opção HTTP Controller

 

I – Acrescentaremos o seguinte conteúdo em app/Controllers/Http/HomeController.js

 

J – Não podemos esquecer de alterar a rota /. No arquivo start/routes.js, substitua:

Por

 

H – E vamos, por último alterar a view resoures/views/home/index.edge para

Adicionamos aqui mais um form com Method spoofing para poder mascarar um verbo HTTP PATCH dentro de um POST

 

 

2.11 Testando o app

Com esta última atualização da view home.index concluídos nossa pequena aplicação utilizando o Adonis. Veja como ficou:

 

 

Conclusão

Neste artigo tivemos uma introdução prática ao AdonisJs através da criação de um APP para gerenciamento de eventos.

Pra quem quiser, aqui está o link do Github do nosso projetohttps://github.com/escola-de-javascript/introducao_adonisjs

A documentação do Adonis está bem organizada e você pode dar uma navegada no link para poder aprender mais sobre o que ele tem de incrível

https://adonisjs.com/docs/4.1/installation

Comente a baixo pra sabermos se você gostou do artigo e se gostaria de uma continuação. Se tivermos respostas bem positivas, vou continuar esse APP e transformá-lo numa série sobre o Adonis abordando estes e outros assuntos.

Obrigado pessoal,
Até o próximo artigo o/

 





5 1 vote
Article Rating
janeiro 17, 2020
Subscribe
Notify of
guest
7 Comentários
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Wemerson
Wemerson
3 anos atrás

Parabéns por esta publicação, muito bem explicado, gostaria de ver á continuação desse App. Abraços

Admin

Obrigado pelo Feedback o/

Leonardo
Leonardo
3 anos atrás

Parabéns Pela iniciativa.

Admin
Reply to  Leonardo

Obrigado pelo comentário 🙂

Ricelli
Ricelli
3 anos atrás

Parabéns pela publicação, curti muito. Acompanhei e consegui já ter uma noa noção do AdonisJs. Algum problema em adicionar este projeto em meu github?

Admin
Reply to  Ricelli

E ai Ricelli, tudo bem?
Ficamos felizes que tenha curtido 🙂
Pode adicionar sim,
Grande abraço

Matheus alves
Matheus alves
3 anos atrás

Quero agradecer pela grande ajuda que sua publicação me trouxe, mas também gostaria de pedir uma ajuda se não for pedir muito. Estou com dificuldade na parte de autenticação com jwt, até consegui fazer o registro do usuário, obter o token jwt e armazenar no localStorage, a minha dúvida é como passar esse token nas chamadas das rotas dentro das views, se puder me ajudar eu ficaria muito grato.

Feito com s2 por OneBitCode

7
0
Would love your thoughts, please comment.x
()
x
%d blogueiros gostam disto: