Como Criar uma Aplicação Full-Stack com React 1/3

Samuel Monteiro
Training Center
Published in
10 min readOct 16, 2018

Criando a API com Node e Express

“Spider-Man leaning on concrete brick while reading book” by Raj Eiamworakul on Unsplash

Fala galera, tudo certo? Então, fui tentar aprender React… Afinal de contas, já tinha visto tutoriais de Vue, até criei uma aplicação simples que consumia dados de uma API escrita em node e que estava funcionando legal. O que poderia dar errado não é mesmo?

Muita coisa deu errado e para ser bem sincero, foi uma das bibliotecas que mais demorei para aprender. No começo até achei meio ruim (minha zona de conforto gritando de saudades), mas disse para mim mesmo que continuaria e que mesmo não gostando de início, iria pelo menos fazer uma aplicação simples.

Então, após um tempo de leitura de artigos e tutoriais, muitos erros e acertos, horas em frente ao VS code tentando entender como que o código que eu tinha acabado de escrever funcionava, decidi por escrever um tutorial para criação de um app em React, desde a criação da API até a interface, pois, nada melhor para aprender do que ensinar não é mesmo?

Nesta série de tutoriais, vou guiar vocês na criação de uma To-do list. Indo desde a criação do servidor express que irá fazer conexão com o banco de dados MongoDB através do mongoose, até a criação das interfaces, utilizando React, Redux e um framework de css chamado bulma.

Bom, sem mais enrolação, bora lá começar.

Os outras duas partes:
Parte 2: Criando os componentes com React
Parte 3: Conexão com o servidor com Redux e Axios

Configurando o Ambiente de Desenvolvimento React

Para começarmos o desenvolvimento vamos digitar o comando npx create-react-app react-todo-bulma, que irá criar uma pasta para nós com o nome de react-todo-bulma e dentro dela, uma estrutura com o necessário para o início do desenvolvimento com React.

Após finalizar toda a instalação, vamos testar. Digite o seguinte comando.

cd react-todo-bulma
npm start

E agora, se tudo deu certo, você deve ter algo parecido com isto no seu navegador.

Site inicial do create-react-app

Pronto, você já tem uma aplicação React rodando :)

Criando o Servidor com Express e mLab

Nossa API ficará dentro de uma pasta /server e dentro dela ficarão os arquivos responsáveis pela criação do servidor, assim como sua lógica e a conexão com o banco de dados.

Bora lá.

1. Estruturando a pasta

A primeira coisa a fazer é criar a estrutura de pastas digitando o comando abaixo na raiz do projeto.

mkdir server
cd server
mkdir config controllers models routes
  • config: Arquivos relacionados a configuração do banco de dados.
  • controllers: Definição das controllers que serão passadas para as rotas.
  • models: Modelos do banco.
  • routes: Definição dos endpoints da API.

Agora você deve ter uma estrutura igual a esta.

├── server/
├── config/
│ ├── controllers/
│ ├── models/
│ ├── routes/

Esta é a estrutura que escolhi para este projeto, por se tratar de algo simples. Porém, para projetos mais complexo e escaláveis, recomendo adotar outro tipo de abordagem(isso vai de gosto pessoal).
Link para um discussão sobre os diferentes tipos:
https://gist.github.com/lancejpollard/1398757

2. Criando o servidor

Instale os seguintes pacotes.

npm install express body-parser --save
npm install nodemon --save-dev
  • express é um framework que visa facilitar a criação de APIs utilizando node.
  • body-parser é responsável por transformar a requisição do cliente em um objeto JSON e o tornar acessível através do req.body(vamos ver mais a frente).

nodemon é opcional, porém extremamente recomendado para desenvolvimento, já que qualquer alteração no código reinicia o servidor. Removendo a necessidade de fazer isso manualmente.
Caso não queira utilizar, para iniciar o servidor utilize o comando node server.js.

Agora, dentro da pasta server, crie um arquivo chamado server.js.

./server/server.js

Com este arquivo definido, você já pode rodar a aplicação através do comando nodemon server.js.

Se tudo correu bem, você deve ter o seguinte texto no terminal

Server listening on port 3001

Para facilitar, podemos adicionar o comando "server": "nodemon server/server.js" dentro dos scripts do package.json. Ai é só digitar no terminal npm run server que ele irá funcionar normalmente.

3. Definindo o modelo

Vamos utilizar um framework chamado mongoose , que facilita a conexão, criação de queries, criação de schemas e validação no MongoDB.

Para instalar o mongoose, digite npm install mongoose --save.

Agora, crie um arquivo dentro da pasta ./modelscom o nome de Task.js.

./server/models/Task.js

Com este arquivo já temos om objeto que servirá de modelo para a criação de um documento, que no caso é a nossa Task. É como se o que tivéssemos acabado de escrever fosse a planta de uma casa de um condomínio, e o que vamos criar serão as casas deste condomínio.

5. Criando as controllers

As controllers são as lógicas responsáveis pelas operações de entidade. Basicamente, vamos criar o CRUD de para a entidade Task e enviar esta lógica através de um objeto para as nossas rotas.

Para as controllers, vamos exportar um objeto contendo todas as ações relacionadas à Task. Add Task, Get All Tasks, Delete Task e Update Task.

Vamos começar com o método add task

Aqui, atribuímos à variável task um novo objeto do tipo Task , passando para ele os atributos do body da requisição. Depois salvamos este objeto com o comando task.save() e através das promises nós retornamos ao cliente uma resposta.

O comando then só é executado caso o comando task.save dê certo, caso contrário é executado o método catch .

Método get all tasks

O método find pode receber como primeiro parâmetro uma query de busca, caso não receba, que é o caso acima, ele retorna todas as tasks.

Método get task by id

O método findById recebe como primeiro parâmetro um id, retornando apenas a task com aquele id específico.

Método delete task

Através do comando findByIdAndRemove nós podemos pesquisar uma Task apenas passando como parâmetro um id e caso for encontrada a deletar.
Como vamos ver mais a frente, o id é passado através da URL da API e por isso pôde ser acessado através do req.params.

Método update task

Aqui utilizaremos o mesmo conceito do método para deletar uma Task, só que desta vez passaremos como segundo argumento o req.body que irá conter toda a estrutura da Task modificada e enviada pelo cliente.

No final, seu arquivo ./controllers/Task.js deve estar como o seguinte

./server/controllers/Task.js

6. Definindo os endpoints

Endpoint basicamente é a URL de um site. Podemos definir que quando um endpoint for acessado a partir de um método HTTP especifico receberemos em nosso servidor uma requisição e executaremos uma ação relacionada ao tipo de requisição retornando ao usuário uma resposta.

Para criar as nossas endpoints, vamos utilizar a classe Router do express para facilitar seu desenvolvimento e gerenciamento. Como primeiro argumento, passaremos o endpoint que a URL deve ter para então executar a controller passada dentro do método HTTP. Com o código vai ficar mais fácil entender.

Dentro da pasta routes crie um arquivo chamado Task.js

Aqui foram definidas duas rotas, cada uma com seus endpoints, seus métodos HTTP e seus respectivos controllers. A primeira rota será acessada quando a URL for igual à / e poderá executar duas controllers, a de adição(add) e a de buscar todas as tasks(getAll) através dos métodos POST e GET respectivamente. Já a segunda rota, só será acessa quando houver um :id após a /.

Tá, mas o que é esse :id?

Isso é um parâmetro que a nossa rota aceita e chama de id e que poderá ser acessado na aplicação através do atributo req.params.id .
Pensando desta forma, se criássemos uma rota denominada /:taskId acessaríamos ela através do atributo req.params.taskId.

Agora, para que nossa aplicação possa identificar e utilizar as rotas que definimos precisamos modificar pouca coisa no arquivo server.js (sendo assim, vou ocultar o restante do código, para ficar mais objetivo).

linhas para adicionar ao server.js

Primeiro estamos importando o objeto Router e atribuindo ele à variável TaskRoutes. Depois utilizamos um comando do express que é o .use e passamos dois argumentos, o primeiro é um caminho ‘base’ a ser utilizado e o segundo é um objeto da classe Router. Com isso, estamos dizendo para a aplicação que para acessar as rotas definidas no objeto TaskRoutes a URL precisa conter o caminho /api/tasks.

Dessa forma, caso o usuário queira buscar todas as tasks ele precisará acessar a URL http://localhost:3001/api/tasks e caso queira atualizar uma task especifica, precisará acessar http://localhost:3001/api/tasks/:id. Esse padrão se aplicará a todas as rotas definidas dentro do arquivo ./routes/Task.

Agora que já temos as rotas definidas e as controllers criadas, só precisamos de um banco de dados e é ai que entra o mLab.

5. Criando um banco de dados no mLab

mLab is the leading Database-as-a-Service for MongoDB, powering over half a million deployments worldwide.

Então basicamente, ele disponibiliza para você um banco de dados MongoDB na nuvem. E o melhor, eles possuem um plano grátis com 500 MB disponíveis.

Para começar a utilizar o serviço, é simples, basta entrar no site escolher o plano “free” e criar uma conta.

Após a criação da conta, é só criar uma nova instância de um banco de dados.

Clique em Create new

Ele então pedirá para você informar o provedor de cloud que você deseja utilizar, o tipo de plano, além da localização do servidor e o nome do banco.

Escolha o servidor e o tipo de plano

Se tudo correu, bem você já tem um banco de dados rodando na nuvem :)

Agora precisamos cadastrar um usuário que terá acesso para manipulação do banco.

Clique em ‘Add database user’

Ele vai pedir um nome de usuário e senha. Após a criação você deve ter algo parecido com isso.

Destacado em vermelho está a URI que iremos utilizar para conectar a API ao banco de dados.

Tudo pronto, agora só precisamos fazer as conexões e testes.

6. Conectando a API ao mLab

Agora vamos ao código que vai conectar a nossa API ao mLab.

Dentro da pasta /config crie um arquivo chamado keys.config.js

./config/keys.config.js

Agora é só copiar a URI que foi criada para o nosso banco de dados e colocar no arquivo acima.

Próxima etapa é fazer a conexão propriamente dita, e para isso vamos utilizar o mongoose.

Vamos editar o arquivo server.js adicionando os comandos de conexão.

linhas para adicionar ao server.js

A primeira coisa que fizemos foi importar o mongoose e as configuração que havíamos definido. Logo depois, através do método mongoose.connect passamos a mongodbUri do banco que criamos e basicamente já está feita a lógica da conexão.

Utilizamos then e catch apenas para termos informação no console sobre o sucesso ou erro de conexão.

Os comandos useNewUrlParser: true e mongoose.set('useFindAndModify', false) servem para que não apareça nenhuma mensagem de DepreciationWarning no console.

O seu arquivo server.js deve estar parecido com este

./server/server.js

Para testar se está tudo funcionando, digite no terminal npm run server ou nodemon server.js. Caso tudo dê certo, você deve ter algo como

Server listening on port 3001
Database connected

Perfeito, agora nos resta o último passo, que é realizar os testes para validar as controllers.

7. Testando e finalizando

Para testar nossa API vou utilizar o Postman para enviar requisições e receber respostas da nossa API.

Após ter o Postman instalado, caso não esteja rodando, vamos iniciar nosso servidor através do comando npm run server.

Agora com o Postman aberto, vamos digitar a URL http://localhost:3001/api/tasks , definir o método como POST e colocar o seguinte na aba Body.

{
"title": "Tarefa 1",
"details": "Minha primeira tarefa",
}

Você deve ficar com algo parecido com isto. Ai é só apertar o botão Send.

E de resposta deve ter algo como

{
"completed": false,
"creation_date": "2018-10-03T02:20:38.865Z",
"_id": "5bb42926c2e08f3608207945",
"title": "Tarefa 1",
"details": "Minha primeira tarefa",
"__v": 0
}

Pronto, você já tem uma Task criada :D

Para vermos esta Task, vamos digitar alterar o método POST para GET e clicar em Send.

Se tudo correu bem, você agora deve ter uma lista contendo apenas uma Task.

[
{
"completed": false,
"creation_date": "2018-10-03T02:20:38.865Z",
"_id": "5bb42926c2e08f3608207945",
"title": "Tarefa 1",
"details": "Minha primeira tarefa",
"__v": 0
}
]

Agora, vamos alterar o detalhe desta Task. Para isso, mude o método GET para PUT, no lugar da URL coloque http://localhost:3001/api/tasks/_id onde o _id é o id da Task e no body da requisição coloque o seguinte

{
"details": "Minha primeira tarefa foi criada e editada sucesso!!"
}

Agora é só clicar em Send e agora deve ter tido o retorno da Task de mesmo id só que com o campo details modificado. Se sim, tudo funcionou como deveria.

Agora para testarmos a remoção, vamos alterar o método para DELETE e manter a mesma URL que utilizamos para atualizar e clicar em Send. E como retorno deve ter recebido o _id da tarefa que foi excluída.

Você pode mudar o retorno da ação de exclusão, basta modificar a controller relacionada à ela.

Pronto, agora já temos uma API funcionando e salvando dados na nuvem. O próximo passo é desenvolver o cliente que vai consumir estes dados e para isso vamos utilizar React, Redux e o framework de css bulma. Mas isso fica para a próxima.

Vlw galera, Abs ✋

--

--

Samuel Monteiro
Training Center

Tech lead na Captalys | apaixonado por programação e desenvolvimento pessoal | Dev React e Typescript