Criando um servidor em NodeJS - Parte 1
Tags: node, javascript
Published: 2020-08-23 18:44:40

Este tutorial, dividido em duas partes ([Parte 2](https://dev.to/devbaraus/criando-um-servidor-em-nodejs-parte-2-6g7)),  ensina como iniciar um servidor Rest API em NodeJS da forma mais trivial. Dessa forma, é utilizado apenas um arquivo JSON, dispensando o uso de sistema gerenciador de banco de dados. Assim, este artigo tem o objetivo de auxiliar programadores iniciantes.

> Repositório [https://github.com/devbaraus/post_server_node](https://github.com/devbaraus/post_server_node)
> Meu site [baraus.dev](https://baraus.dev)

Abaixo são listados alguns dos conhecimentos que serão descritos e ensinados neste tutorial:

- Boas práticas de programação
- Definição de um sistema de pastas simples e eficiente
- Iniciar um repositório Git
- Iniciar um projeto Node utilizando yarn
- Ler e manipular arquivos usando Node
- Criar um <abbr title="Create, Read, Update and Delete">CRUD</abbr> (Criar, Ler, Alterar e Deletar) simples
- Usar o prompt de comando/terminal

Antes de começar é preciso certificar-se de que alguns programas estão instalados na máquina que será utilizada para realizar este tutorial.

- [NodeJS](https://nodejs.org/en/download/), ambiente de execução de código JavaScript. Este programa permite executar JavaScript fora do navegador.
- [Yarn](https://classic.yarnpkg.com/en/docs/install), gerenciador de pacotes JavaScript.
- [Git](https://git-scm.com/), versionador de código.
- [Visual Studio Code](https://code.visualstudio.com/), editor de código.
- [Insomnia](https://insomnia.rest/), ambiente para testar requisições HTTP.

É necessário criar uma conta criada no [GitHub](https://github.com/). O GitHub é a plataforma de hospedagem de código-fonte e possui controle de versão. Essa plataforma poderá auxiliar no transporte do código para outro lugar, como para a faculdade ou trabalho.

É importante saber o que é um servidor REST, o que é HTTP e como utilizar o Insomnia para fazer requisições ao servidor HTTP. Para isso foram separados alguns links demonstrar o que está sendo montado:

- [O que é API Rest e Restful?](https://becode.com.br/o-que-e-api-rest-e-restful/) (post)
- [ENTENDENDO O PROTOCOLO HTTP](http://blog.leandrocurioso.com/2017/05/entendendo-o-protocolo-http/) (post)
- [Insomnia](https://www.youtube.com/watch?v=3tB0uDliS6Y) (vídeo).

Iniciando o projeto.

Lembrando que os passos a seguir são realizados em um terminal bash, o mesmo utilizado em sistemas operacionais Linux.

## Tabela de conteúdos
- [Criando pastas](#criando-pastas)
- [Criando um repositório utilizando GitHub](#criando-um-repositório-utilizando-github)
- [Criando um repositório sem GitHub](#criando-um-repositório-sem-github)
- [Criando package.json usando Yarn](#criando-packagejson-usando-yarn)
	- [Instalando os primeiros pacotes](#instalando-os-primeiros-pacotes)
	- [Scripts](#scripts)
- [REST com Express](#rest-com-express)
	- [Domínio](#domínio)
	- [Porta](#porta)
	- [Rota](#rota)
	- [Cabeçalhos](#cabeçalhos)
		- [Métodos](#métodos)
			- [GET](#get)
			- [POST](#post)
			- [PUT](#put)
			- [DELETE](#delete)
	- [Corpo](#corpo)
	- [Parâmetros (Query String)](#parâmetros-query-string)
	- [Recapitulando REST com Express](#recapitulando-rest-com-express)
		- [GET](#get-1)
		- [GET com parâmetros](#get-com-parâmetros)
		- [GET com rota dinâmica](#get-com-rota-dinâmica)
		- [POST](#post-1)
		- [PUT](#put-1)
		- [DELETE](#delete-1)
- [Recapitulando](#recapitulando)

# Criando pastas

Para começar será criada uma pasta inicial chamada **server_node**. Após criá-la é necessário entrar nela

```bash
mkdir server_node # cria pasta server_node
cd server_node # entra na pasta
```

Depois é criada uma pasta chamada **src**. Nessa pasta todos os arquivos de desenvolvimento do projeto são depositados.

```bash
mkdir src # cria pasta src
cd src # entra na pasta
```

Por enquanto, tem-se apenas a pasta **server_node** e dentro dela uma pasta chamada **src**. Porém, dentro da pasta **src** ainda deve ser criada uma hierarquia de pastas.

Uma pasta chamada **controllers**, na qual estarão os códigos que controlaram as funcionalidade do usuário, e outra chamada **db**. Na pasta db estarão todas a informação do base de dados, neste caso um arquivo .json com alguns dados.

Para criar essas pastas é executado o seguinte comando:

```bash
mkdir controllers db # cria as duas pastas em uma linha
```

Para os próximos passo é necessário que o diretório atual seja a **raiz** do projeto, ou seja, a pasta **server_node**. Lembrando que o diretório atual é **src** dentro de **server_node**. Para voltar diretórios execute.

```bash
cd ../ # volta uma pasta
```

# Criando um repositório utilizando GitHub

Caso você tenha uma conta criada no GitHub, [crie um novo repositório](https://github.com/new) com nome **server_node**, sem gitignore, licença e readme.
Logo após criado o repositório irá aparecer algumas opções para iniciar o mesmo. Copie todo o conteúdo da opção **criar um novo repositório usando linha de comando**, no meu caso o código é o mostrado abaixo. Cole o conteúdo no terminal e de enter.

```bash
echo "# server_node" >> README.md # cria um arquivo com o conteúdo "# server_node"
git init # inicia um repositório git local
git add README.md # adiciona o arquivo ao commit
git commit -m "first commit" # adiciona uma mensagem ao commit
git remote add origin https://github.com/devbaraus/server_node.git # vincula o repositorio do github ao seu repositorio local
git push -u origin master # envia o estado atual do seu repositório para o GitHub
```

# Criando um repositório sem GitHub

Caso você não utilize o GitHub ou qualquer outra plataforma. Apenas copie e cole o código abaixo para iniciar seu versionamento de código local.

```bash
git init # inicia repositório git local
```

Pronto!

# Criando package.json usando Yarn

Para iniciarmos um projeto NodeJS é muito simples, apenas precisamos criar um arquivo chamado **package.json** com algumas propriedades, como:

- name, nome do projeto
- description, descrição do projeto
- version, versão atual do projeto
- main, arquivo principal do projeto
- author, autor do projeto
- license, licença utilizada no projeto
- private, se este projeto pode ser publicável ou não
- scripts, comandos de execução
- dependencies, dependências principais do projeto
- devdependencies, dependências apenas utilizadas no desenvolvimento

Embora seja algo simples de se criar na mão, é muito mais fácil utilizando um comando que o Yarn disponibiliza. Este comando se chama **yarn init**, após executar, será necessário preencher alguns dados, como é mostrado abaixo.

```bash
yarn init # inicia repositório git local
```

```
question name (server_node):
question version (1.0.0): 0.0.1
question description: Servidor em nodejs
question respository url: https://github.com/devbaraus/post_server_node.git
question author: Bruno de Araujo Alves <devbaraus>
question license (MIT): MIT
question private: false
```

Preenchido todos os comandos seu arquivo deve se parecer como o mostrado abaixo.

<p align="center">
<img src="https://res.cloudinary.com/dmzu6cgre/image/upload/v1598310567/public/posts/server_node/package_json_sxzlrk.png" title="package.json" width="384px">
</p>

## Instalando os primeiros pacotes

Pacotes são módulos, códigos que outras pessoas fizeram para realizar alguma coisa.
Neste projeto utilizaremos poucos pacotes, sendo eles classificados em principais ou desenvolvimento. Como o nome já sugere, pacotes principais são módulos que seu código irá precisar mesmo quando em produção e pacotes de desenvolvimento são módulos que você usará apenas quando estiver programando.
Módulos que usaremos são:

Principais

- Express, possibilita criarmos um servidor http utilizando node
- cors, possibilita que uma outra aplicação faça requisição ao seu servidor

Para instalar use

```bash
yarn add Express cors
```

Desenvolvimento

- morgan, possiblita gerar logs de toda requisição feita ao servidor
- nodemon, possibilita que executemos nosso servidor e a cada alteração no código o servidor seja reiniciado.

E para instalar os pacotes em modo de desenvolvimento, apenas adicione mais um argumento **-D** .

```bash
yarn -D add morgan nodemon
```

Seu package.json deve estar semelhante a este.

<p align="center">
<img src="https://res.cloudinary.com/dmzu6cgre/image/upload/v1598310567/public/posts/server_node/package_json_dependencies_da9zho.png" title="package.json com dependencias" width="384px">
</p>

Se atente que ao instalar um novo pacote uma pasta chamada **node_modules** é criada, nela está todos os pacotes baixados. Ainda, note que cada vez que você adiciona ou remove um pacote o arquivo **package.json** é alterado. Isso serve para caso você precise copiar seu código para outra máquina, você não precise copiar a pasta **node_modules** junto, e seja necessário apenas executar o comando.

```bash
yarn install # instala todos os pacotes do package.json
```

Com esse comando todos os pacotes que estejam no **package.json** serão instalados e automaticamente será criada a pasta **node_modules**.

## Scripts

Agora que temos os pacotes instalados podemos criar alguns scripts para executar nosso servidor. Primeiro vamos criar uma nova propriedade no arquivo **package.json** chamada **scripts** e esta receber um objeto vazio.

```json
"scripts": {},
```

Dentro de **scripts** vamos criar duas propriedades, **dev** e **start**.
**Dev** será o script para executarmos o servidor em desenvolvimento, reiniciando a cada modificação no código.

```json
"scripts": {
	"dev":  "nodemon --watch ./src/**/* ./src/server"
},
```

E o **start** será o script que utilizaremos quando quisermos executar nosso servidor em produção.

```json
"scripts":  {
	"dev":  "nodemon --watch ./src/**/* ./src/server",
	"start":  "node ./src/server"
},
```

Seu package.json agora deve estar semelhante ao mostrado abaixo.

<p align="center">
<img src="https://res.cloudinary.com/dmzu6cgre/image/upload/v1598310567/public/posts/server_node/package_json2_nxyxwo.png" title="package.json com scripts e dependências" width="384px">
</p>

# REST com Express

Antes de começarmos a codar precisamos lembrar de alguns conceitos de requisições HTTP.
Para fazermos uma requisição HTTP com **Express** precisamos lembrar de 6 pontos principais: o domínio, a porta, a rota, os cabeçalhos (headers), o corpo (body) e os parâmetros (query string).

## Domínio

Domínio, de forma bem ampla, é o nome do servidor, este é um jeito utilizado para não precisarmos escrever o IP de todo site que quisermos acessar. O domínio, assim como o IP, é único e é reconhecido por toda a internet. Como exemplo, a Google tem um domínio global `google.com`
que por trás está um IP `172.217.28.78`.

A única exceção de domínio e IP que se repete em toda máquina é o local. Toda máquina máquina consegue se acessar usando o domínio local `localhost` e IP `127.0.0.1`, portanto uma máquina não consegue acessar um aplicação de outra máquina utilizando o domínio `localhost`, pois ela tentará acessar a si mesma.

## Porta

Porta, de forma ampla, são conexões de cada aplicação dentro da nossa máquina. Cada aplicação utiliza uma ou mais portas para se comunicar com outra aplicação, internamente ou não. Em nossa máquina temos 65535 portas, sendo 1024 reservados para uso do computador.

Lembrando que por padrão HTTP utiliza a porta 80, por isso muita das vezes não precisamos explicitamente colocar a porta ao acessar um site.
Faça o teste, acesse `google.com:80` e depois `google.com:82`. No primeiro caso você conseguirá acessar o site, porém no seguindo caso o navegador não conseguira acessar nada.

Nesse projeto, nosso servidor utilizamos a porta 3000, porém pode ser alterado para qualquer valor entre 1024 e 65335.

## Rota

Rota, é o caminho em que o usuário faz uma requisição ao servidor.
Sendo assim, um caminho dita qual conteúdo você espera que o servidor te retorne.
Como exemplo novamente a Google: `google.com/` e`google.com/doodles/`
No primeiro caso falamos ao servidor que esperamos a página de busca do site `/` , já no segundo caso pedimos ao servidor do google que nos mostre a página doodles `/doodles/`.

Servidores têm a possibilidade também de criar rotas dinâmicas, estas são rotas geradas automaticamente para requisição de um dado específico mas que o tratamento desse dado é genérico. Como, buscar dados de um usuário específico. O servidor irá retornar os dados apenas daquele usuário, porém o tratamento no servidor é genérico, de forma que consiga buscar qualquer usuário dentro do banco de dados.

## Cabeçalhos

Os cabeçalhos têm informações importantes sobre o usuário e também sobre o servidor (no retorno).
Nos cabeçalhos conseguimos encontrar o método/verbo da requisição (GET, POST, PUT, DELETE, entre outros), o tipo do conteúdo da requisição, o tamanho do conteúdo enviado na requisição, qual aplicação fez a requisição, o domínio em que o usuário está, entre outros.

### Métodos

Como dito antes, nos cabeçalhos é possível encontrar o método/verbo da requisição, sendo os mais conhecidos:

- GET
- POST
- PUT
- DELETE

Embora nem sempre mudamos outros conteúdos do cabeçalho, no servidores com **Express** sempre precisamos falar quais métodos estamos utilizando para uma determinada rota.

> Navegadores por padrão utilizam apenas os métodos GET e POST, portanto, para utilizar outro método é necessário utilizar JavaScript em uma requisição.

#### GET

Por padrão é utilizado quando queremos apenas o retorno de algum dado/página do servidor.

#### POST

Utilizado quando estamos enviando dados, como um formulário para servidor. Geralmente usado para criar um dado novo no servidor ou fazer um login de usuário.

#### PUT

Utilizado quando estamos enviando dados, como um formulário para servidor, porém, desta vez estamos modificando um dado já existente.

#### DELETE

Utilizado quando queremos deletar um dado existente.

## Corpo

Corpo é um espaço na requisição HTTP onde os dados de um formulário são enviados ao servidor. Há vários tipos de conteúdos que podem ser enviados no corpo, por isso do campo `tipo de contéudo` dentro dos cabeçalhos.

## Parâmetros (Query String)

Parâmetros, como o nome já indica, são parâmetros que passamos junto a rota, geralmente são utilizados como filtros para alguma requisição.

Um exemplo de parâmetro sendo passado para o servidor da Bing, onde pedimos ao servidor que nos retorne pesquisas relacionadas a `restapi`:

```
www.bing.com/search?q=restapi
```

Para criar um parâmetro precisamos iniciar com **`?`**, seguido de **`campo=valor`**, caso queira adicionar mais parâmetros apenas insiria **`&`** seguido de **`campo=valor`**, como abaixo:

```
www.bing.com/search?q=restapi&form=QBLH
```

Geralmente os parâmetros são utilizados junto ao método GET, para filtragem de resultados no servidor. Porém nada impede de ser usados junto a outro método HTTP.

## Recapitulando REST com Express

Agora que foi esclarecido alguns pontos principais de um servidor HTTP. Vamos ver alguns exemplos:

---

### GET

- Método: GET
- Rota: /nomes:
- URL: `http//localhost:3000/nomes`
- Funcionalidade: retornar todos os nomes

```js
app.get('/nomes', (req, res) => {
	...
})
```

---

### GET com parâmetros

- Método: GET
- Rota: /nomes
- Parâmetros: `?maxLength=6&fisrtLetter=a`
- URL: `http//localhost:3000/nomes?maxLength=6&fisrtLetter=a`
- Funcionalidade: retornar todos os nomes com o tamanho máximo de **6** letras que comecem com a letra **a**

```js
app.get('/nomes', (req, res) => {
	const { maxLength, firstLetter } = req.query // pega os parametros
	...
})
```

---

### GET com rota dinâmica

- Método: GET
- Rota: /nomes/bruno
- URL: `http//localhost:3000/nomes/bruno`
- Funcionalidade: retornar informações sobre o nome **bruno**

```js
app.get('/nomes/:nome', (req, res) => {
	const { nome } = req.params // pega valor da rota dinâmica
	...
})
```

---

### POST

- Método: POST
- Rota: /nomes
- Corpo: `{ nome: 'bruno', significado: 'moreno, escuro' }`
- URL: `http//localhost:3000/nomes`
- Funcionalidade: criar um novo nome com significado

```js
app.post('/nomes', (req, res) => {
	const { nome, significado } = req.body // pega campos do corpo
	...
})
```

---

### PUT

- Método: PUT
- Rota dinâmica: /nomes/bruno
- Corpo: { significado: 'claro' }
- URL: `http://localhost:3000/nomes/bruno`
- Funcionalidade: alterar o significado do nome **bruno**

```js
app.put('/nomes/:nome', (req, res) => {
	const { nome } = req.params // pega valor da rota dinâmica
	const { significado } = req.body // pega o campo do corpo
	...
})
```

---

### DELETE

- Método: DELETE
- Rota dinâmica: /nomes/bruno
- URL: `http://localhost:3000/nomes/bruno`
- Funcionalidade: deletar o nome **bruno**

```js
app.delete('/nomes/:nome', (req, res) => {
	const { nome } = req.params // pega valor da rota dinâmica
	...
})
```

# Recapitulando

Finalmente, completamos o que foi proposto nessa parte. Criamos nosso sistema de pastas, utilizamos o terminal para executar alguns comandos, inicializamos nosso repositório, iniciamos o projeto com Yarn, instalamos alguns módulos, criamos os scripts que vamos utilizar no projeto e foi explicado por cima como fazer uma requisição HTTP.

Agora estamos prontos para ir para a próxima fase, onde realmente colocamos a mão na massa e criamos nosso primeiro servidor com NodeJS.

Gostaria de agradecer de você ter chegado até aqui! Espero que eu tenha lhe passado algum conhecimento. Então vamos para a parte 2 desse tutorial!