No projeto de hoje, vamos fazer uma API simples usando NodeJS.
Essa api vai ser bem simples mas já nos dará uma base bem sólida para alguns conceitos de construção de APIs como rotas, requisições e verbos HTTP.
E vamos criar tudo passo-a-passo, do absoluto zero!
Conteúdo do post
Pré-Requisitos
Para esse projeto, você precisa do NodeJS instalado em sua máquina, você pode fazer o download e seguir as instruções para o seu sistema operacional diretamente do site deles.
Após fazer a instalação do NodeJS, você deve criar a pasta onde ficará seu projeto. Pelo terminal vá até essa pasta.
Agora vamos criar o arquivo package.json utilizando o seguinte comando:npm init -y
Pronto! Os pré-requisitos foram cumpridos.
Instalando Express
Agora vamos instalar o Express, que é um framework do NodeJS para criação de aplicações web. Essa instalação é bem simples, basta usar o seguinte comando do NPM:npm install --save express
Agora que temos o Express instalado, vamos criar um arquivo chamado index.js que será a porta de entrada da nossa aplicação.
No index.js coloque o seguinte conteúdo:
const express = require('express'); const app = express(); const port = 3000; app.get('/', (req, res) => res.send('Minha API')); app.listen(port, () => console.log(`Listening on port ${port}!`));
Agora vamos rodar esse arquivo, utilizando o comando:node index.js
Ao executar esse comando, você vai ver um log no terminal dizendo “Listening on port 3000!”, isso significa que o nosso servidor foi inicializado com sucesso e que está pronto para responder requisições no endereço http://localhost:3000 (url localhost, porta 3000).
Agora você pode abrir o seu browser em http://localhost:3000 que o servidor irá responder com o texto “Minha API”
Métodos HTTP
Agora vamos analizar a fundo a linha
app.get('/', (req, res) => res.send('Minha API'));
.
Lembra quando a gente inicializou o Express atribuindo ele à constante app
? Esse objeto app
, contém vários métodos do servidor Express e dentro desses métodos temos os verbos HTTP como funções que irão responder a requisições.
Se você não conhece os verbos HTTP, aqui vai uma pequena explicação:
Existem vários verbos referentes a tipos diferentes de requisições HTTP, entre eles os mais comuns são GET, POST, PUT e DELETE.
Esses verbos ajudam a identificar tipos diferentes de requisições em uma determinada rota. Por exemplo, usamos o GET para pegar informações, o POST para enviar informações, o PUT para atualizar informações e o DELETE para remover informações.
Esses verbos HTTP também se referem às operações CRUD, Create, Read, Update e Delete, que vamos ver mais pra frente.
Sabendo o que você já sabe agora, vamos voltar ao nosso objeto app
. Ele tem os métodos referentes aos verbos HTTP, então podemos criar as nossas rotas da seguinte formaapp.METODO(CAMINHO, FUNÇÃO);
O método GET
Então agora quando você vê o métodoapp.get('/', (req, res) => res.send('Minha API"));
você já consegue entender que estamos chamando o “GET” no caminho “/” (raiz da nossa url) e temos depois como callback uma arrow function.
Essa arrow function, poderia ser substituída por uma função normal, como por exemplo:
app.get('/', function(req, res) { return res.send('Minha API')); });
ou até mesmo
function index(req, res) { return res.send('Minha API'); } app.get('/', index);
Tudo isso fica a critério do desenvolvedor e do time.
O mais comum atualmente é usar um JavaScript moderno, ou seja com arrow functions, então vamos deixar assim mesmo:app.get('/', (req, res) => res.send('Minha API'));
Agora que você entendeu o app.get();, você já sabe que existem os métodos app.post();, app.put();, app.delete(); e também alguns outros que não iremos cobrir nesse momento.
Agora vamos falar do req e do res e mais pra frente voltamos no post, put e delete.
Entendendo o req e o res
Vocês devem ter percebido esse tal de req e res e devem estar confusos. Mas vou explicar detalhadamente como funciona.
Internamente o método app.get();
, recebe dois parâmetros, o caminho (também conhecido como path) e no segundo parâmetro uma função de callback.
O callback é uma função que o método get irá executar depois que ele terminar de executar o que ele tem pra executar.
Vou exemplificar o callback pra vocês.
Vou criar uma função chamada fazOperacaoMatematicaSecretaComplexa(numero1, numero2, callback);
Como vocês perceberam essa função recebe 3 parâmetros, numero1, numero2 e callback, e como vocês podem imaginar o numero1 e o numero2 devem ser números e o callback deve ser uma função.
Sim o JavaScript permite que você envie funções como parâmetros.
Essa nossa função fazOperacaoMatematicaSecretaComplexa
não irá retornar nada e ao invés de retornar, elta irá enviar o resultado pelo callback, então vamos colocar a mão na massa e criar nossa função:
Eu adicionei uns comentários ao código, para que você consiga acompanhar.
function fazOperacaoMatematicaSecretaComplexa(numero1, numero2, callback) { // vamos verificar se numero1 é um numero. if (isNaN(numero1)) return; if (isNaN(numero2)) return; // agora que temos os 2 números, podemos fazer nossa operação matemática secreta complexa // e atribuir o resultado a constante result. // nossa operação matemática secreta complexa (multiplicação) const resultado = numero1 * numero2; // agora com o resultado em mãos vamos retorná-lo usando o callback // vamos verificar se o callback é uma função if (typeof callback === "function") { callback(resultado); } }
Agora vamos fazer uma chamada a essa função, passando como numero1 e numero2 o valor 2, e como callback a função console.log
.
fazOperacaoMatematicaSecretaComplexa(2, 2, console.log);
Se você rodar esse arquivo no terminal você irá ver o numero 4 como resultado no console
.
Nesse momento, você deve estar coçando a cabeça e falando assim, mas pra quê esse tal de callback se eu poderia simplesmente retornar o resultado. Sim, você poderia simplesmente retornar o resultado, pois nossa função não executa nada de forma assíncrona. Tenho muito mais pra falar sobre callback mas poderemos nos aprofundar nisso futuramente.
Agora sabendo o que você já sabe sobre callbacks, vamos voltar pro app.get
, internamente ele irá chamar o callback, enviando alguns parâmetros, e os dois primeiros são os objetos req e res que por sua vez contém vários métodos.
O primeiro parâmetro o req, é uma abreviação para request, ou seja, um objeto responsável pela informações e funções referentes a requisição.
O segundo parâmetro é o res, que é uma abreviação para response, ou seja, um objeto responsável pelas informações e métodos de resposta.
Nesse nosso exemplo, simplesmente usamos o res.send()
para enviar a string “Minha API” como resposta a nossa requisição.
Retornando JSON
Agora que já sabemos um pouco mais sobre como funcionam as requisições dentro do Express, vamos alterar a nossa resposta para enviar um JSON ao invés de uma string.
Vamos criar um objeto simples e vamos enviá-lo como resposta, vou chamar esse objeto de result.const result = {name: 'emerson', instagram: 'emersonbrogadev'};
Agora vamos voltar ao nosso app.get
e retornar essa resposta. Ele vai ficar assim:
app.get('/', (req, res) => { const result = { name: 'emerson', instagram: 'emersonbrogadev' }; return res.json(result); });
Agora você deve parar o serviço do NodeJS que está rodando (utilize o comando CTRL + C no terminal) e vamos iniciar o serviço novamente:node index.js
.
Ao acessar http://localhost:3000
no browser, você verá algo como:{ "name": "emerson", "instagram": "emersonbrogadev" }
Pronto, retornamos o nosso primeiro JSON. Isso será a base para todas as nossas APIs REST que a gente criar.
Pode abrir o champagne e comemorar.
POST
Agora vamos fazer uma requisição do tipo POST. Como eu disse anteriormente, nas requisições post a gente envia dados ao servidor.
Então voltando ao nosso servidor Express, vamos criar uma rota post, seguindo o mesmo padrão.app.METODO(CAMINHO, FUNÇÃO);
app.post('/', (req, res) => { return res.json([]); });
A primeira coisa que eu quero apontar aqui, é que o caminho é o mesmo, “/” (raiz da nossa url) o que deixa claro pra gente que podemos usar o mesmo caminho para requisições HTTP diferentes.
Se você reiniciar o serviço do NodeJS que está rodando (CTRL + C) e iniciá-lo novamente com node index.js
e acessar pelo browser http://localhost:3000, você terá como resposta o JSON do nosso método GET, pois quando executamos uma requisição pelo browser, por padrão ela é do tipo GET. Ainda bem que para facilitar a nossa vida, existem ferramentas como o Postman.
A história do POSTMAN
Olha que massa essa historia, alguém foi no StackOverflow, e perguntou “Como que faz pra fazer uma requisição POST pelo browser?” e dentre as respostas mais votadas, o usuário do StackOverflow com o username “Abhinav”, escreveu o seguinte:
Estou trabalhando em um app do Chrome chamado Postman para fazer esse tipo de coisa.
Abhinav (tradução livre)
Isso aconteceu em 2012, e atualmente o Postman é utilizado por mais de 10 milhões de desenvolvedores ao redor do mundo e eu sou um deles e espero que você seja também. = )
Você pode fazer o download gratuitamente em https://www.postman.com/downloads/.
E sim, atualmente existem outras alternativas, mas vamos continuar com o Postman.
Voltando para requisição POST
Feito o download, abra o Postman, clique no botão “+” e selecione o método POST.
Digite a url http:localhost:3000 e clique no botão “Send“, na resposta você verá o array vazio que retornamos como JSON.
Se você teve uma resposta diferente, pode ser que você esqueceu de reiniciar o serviço do NodeJS.
Agora que você já viu como fazer uma requisição GET e uma requisição POST, você deve estar se perguntando, qual a diferença, pois parece que nada mudou, tudo que você teve que fazer foi abrir o Postman para fazer essa requisição. E sim eu entendo essa sua percepção, só que a grande diferença virá agora, como disse anteriormente o método POST serve para enviarmos dados, então vamos utilizar o Postman novamente só que dessa vez enviando dados.
Vá até a aba “body” e com a opção “x-www-form-urlencoded” selecionada, coloque as seguintes chaves e valores (key e value).
name emerson site emersonbroga.com
conforme a imagem abaixo:
E antes de clicar no botão “Send” vamos fazer uma pequena modificação no método de callback do app.post();
Lembra que o req, ou seja, request, contém os dados da requisição? Então vamos usar o req, para pegar os dados que enviaremos em nossa requisição pelo Postman. Porem por padrão o Express, não tem um parser do body (corpo) da requisição, então antes precisamos instalar um middleware chamado “body-parser“, sendo assim, volte ao terminal e execute o seguinte comando:
npm install --save body-parser
Agora vamos adicionar o body-parser em nossa aplicação, primeiro importando o body-parser e em seguida aplicando ele ao nosso servidor Express, com o app.use();
. Juntamente a isso, vamos passar ao body-parser o extended: true
para o método urlencoded, para que possamos também fazer o parser de dados aninhados.
Depois disso tudo seu index.js
ficará da seguinte forma:
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const port = 3000;
app.use(bodyParser.urlencoded({ extended: true }));
app.get('/', (req, res) => {
const result = { name: 'emerson', instagram: 'emersonbrogadev' };
return res.json(result);
});
app.post('/', (req, res) => {
return res.json([]);
});
app.listen(port, () => console.log(Listening on port ${port}!
));
Agora sim, vamos utilizar o req, para pegar os dados da nossa requisição, então no seu método app.post() faça da seguinte forma:
app.post('/', (req, res) => { const name = req.body.name; const site = req.body.site; return res.json([site, name]); });
Reinicie o serviço do NodeJS e execute a chamada no Postman, você verá algo como:
[ "emerson", "emersonbroga.com" ]
Agora você já sabe como funcionam as requisições POST e entendeu até a história do Postman!
O método PUT
Agora que já está mais claro como funciona o GET e o POST, vou falar sobre o PUT. Eu não sei se você já percebeu o potencial do GET e do POST, pois até agora só falamos de dados estáticos.
Em nosso método GET, retornamos de forma estática o JSON "{ name: 'emerson', instagram: 'emersonbrogadev' }"
, mas em uma aplicação real, essas informações não seriam estáticas, elas viriam de alguma outra fonte, como por exemplo um banco de dados, uma API externa, um arquivo em disco, etc, viria de alguma outra fonte. A mesma coisa se aplica para o método POST, estamos apenas recebendo os dados e retornando de modo estático, mas em uma aplicação real, iríamos persistir esses dados de alguma forma, seja um banco de dados, uma api externa, arquivo em disco, etc.
Com tudo isso em mente, eu já posso te dizer que não há muito segredo no método PUT.
No PUT por exemplo, como disse anteriormente, serve para atualizar informações, e no caso de uma API REST, teríamos que passar um identificador para o qual essa atualização seja aplicada. Para isso a rota que iremos utilizar ser á um pouco diferente, pois ela irá conter esse identificador.
No Express, definimos rotas com parâmetros, utilizando o “:” para indicar que é uma variável, então para criar o nosso identificador, vamos usar o :identificador, que ao aplicar a nossa rota ficará app.put('/:identificador', () => {});
Esse identificador será utilizado para buscar o item a ser alterado.
Agora vamos colocar a mão na massa e fazer o seguinte:
app.put('/:identificador', (req, res) => { const identificador = req.params.identificador; return res.json([identificador]); });
Ou seja, estamos pegando esse identificador da url, utilizando o objeto req.params
, que contém os parâmetros da url da rota, nesse caso o identificador.
Vamos voltar ao Postman e vamos fazer a seguinte chamada PUT para a url http://localhost:3000/emerson
onde emerson será o nosso identificador.
Antes de apertar o botão “Send“, lembre-se de reiniciar o servido do node e você verá o identificador sendo exibido em nossa resposta JSON.
Agora vamos fazer algumas mudanças, para tornar o nosso código um pouco mais interessante. Lembra que agora a pouco eu disse que poderíamos usar um banco de dados, uma api, ou arquivo em disco, etc, como nossa fonte de dados? Pra deixar as coisas simples, nesse exemplo, vou utilizar um simples array do JavaScript como nossa fonte de dados.
Eu deixei esse array pronto aqui com alguns dados fictícios, incluindo id, name, age e company (identificador, nome, idade e empresa).
const data = [ { id: 1, name: "Mike", age: 22, company: "Nascetur Mus Company" }, { id: 2, name: "Eleanor", age: 42, company: "Hendrerit Donec LLP" }, { id: 3, name: "Dylan", age: 51, company: "Nisi Incorporated" }, { id: 4, name: "Leila", age: 30, company: "Eros Non Limited" }, { id: 5, name: "Jason", age: 31, company: "Accumsan Interdum Associates" }, ];
Vamos colocar esses dados em nosso index.js
, logo depois da constante port
, deixando o arquivo completo assim:
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const port = 3000;
const data = [
{ id: 1, name: 'Mike', age: 22, company: 'Nascetur Mus Company' },
{ id: 2, name: 'Eleanor', age: 42, company: 'Hendrerit Donec LLP' },
{ id: 3, name: 'Dylan', age: 51, company: 'Nisi Incorporated' },
{ id: 4, name: 'Leila', age: 30, company: 'Eros Non Limited' },
{ id: 5, name: 'Jason', age: 31, company: 'Accumsan Interdum Associates' },
];
app.use(express.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.get('/', (req, res) => {
const result = { name: 'emerson', instagram: 'emersonbrogadev' };
return res.json(result);
});
app.post('/', (req, res) => {
const name = req.body.name;
const site = req.body.site;
return res.json([site, name]);
});
app.put('/:identificador', (req, res) => {
const identificador = req.params.identificador;
return res.json([identificador]);
});
app.listen(port, () => console.log(Listening on port ${port}!
));
Agora vamos mudar um pouco o nosso método PUT.
Primeiramente vamos simplificar as coisas e ao invés de chamarmos de identificador, vamos deixar só como id.
Agora que temos os nossos dados, podemos definir que a chave id que é um número inteiro, que não se repete, será usado como nosso identificador. Ponto importante de um identificador é ele ser único, para que possa identificar apenas um item. Essa é uma definição que você ao criar a sua API faz, decidindo qual será o identificador dos seus dados, nesse exemplo, ficaremos com o id, mas existem diversas outras formas (email, uuid, etc).
Dito isso, após pegarmos o identificador da nossa requisição, vamos procurar esse item em nossos dados, nesse caso vamos usar o método find
dos arrays do JavaScript:
app.put('/:id', (req, res) => { const id = req.params.id; const item = data.find(item => item.id == id); return res.json(item); });
Agora mais uma vez, reinicie seu serviço do node, e faça uma requisição PUT (usando Postman) para a url http://localhost:3000/1
O número 1 é o nosso identificador (id) que corresponde ao item que tem o nome “Mike” em nossos dados, então você terá o seguinte resultado.
Agora nós já conseguimos pegar o item a ser alterado em nossa requisição PUT, mas antes vamos dar uma pausa e analisar um pouco esse código.
O que temos aqui serve perfeitamente para ser o método GET que retorna apenas um elemento. Então vamos duplicar esse nosso código e gerar uma rota GET que retorna um elemento.
app.get('/:id', (req, res) => { const id = req.params.id; const item = data.find(item => item.id == id); return res.json(item); });
Pronto, temos um método GET que retorna apenas um elemento! Reinicie o serviço do NodeJS e vá no Browser ou no Postman e acesse a url http://localhost:3000/1
Altere o id de 1 para outro número e veja se está retornando como esperado.
Só que agora eu tenho 2 notícias pra você, existe um problema nesse código!
Repetição de código é algo que deve ser evitado, então vamos abstrair esse nosso “find
” para um método externo, para que possamos usar na rota GET e na rota PUT (e futuramente também na DELETE).
O seu index.js
ficará assim:
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const port = 3000;
const data = [
{ id: 1, name: 'Mike', age: 22, company: 'Nascetur Mus Company' },
{ id: 2, name: 'Eleanor', age: 42, company: 'Hendrerit Donec LLP' },
{ id: 3, name: 'Dylan', age: 51, company: 'Nisi Incorporated' },
{ id: 4, name: 'Leila', age: 30, company: 'Eros Non Limited' },
{ id: 5, name: 'Jason', age: 31, company: 'Accumsan Interdum Associates' },
];
const findItem = id => {
return data.find(item => item.id == id);
};
app.use(express.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.get('/', (req, res) => {
const result = { name: 'emerson', instagram: 'emersonbrogadev' };
return res.json(result);
});
app.get('/:id', (req, res) => {
const item = findItem(req.params.id);
return res.json(item);
});
app.post('/', (req, res) => {
const name = req.body.name;
const site = req.body.site;
return res.json([site, name]);
});
app.put('/:id', (req, res) => {
const item = findItem(req.params.id);
return res.json(item);
});
app.listen(port, () => console.log(Listening on port ${port}!
));
Ficou bem melhor não é mesmo?
Agora vamos continuar com nosso método PUT, fazendo a alteração do nosso item.
Depois de usar o id para buscar o item, vamos usar o body para pegar o dado a ser modificado, que nesse caso será o nome, em seguida vamos utilizar o spread para atualizar o item da seguinte forma.
app.put('/:id', (req, res) => { const name = req.body.name; let item = findItem(req.params.id); item = { …item, name: name }; return res.json(item); });
Perceba que primeiramente, eu pego o novo nome do body da requisição, da mesma forma que fizemos em nosso método POST, e depois eu mudei o item de const para let, pois um novo valor será atribuído e em seguida atribuí esse novo valor usando o spread e sobrepondo o name como novo name que veio do body.
Existem diversas formas de alcançar o mesmo resultado, eu escolhi utilizar o descrito acima.
Agora você pode reiniciar o serviço e executar a seguinte requisição PUT no Postman:
Uma informação importante para apontar aqui, é que não estamos atualizando de verdade o nosso array de dados, Para isso precisamos de uma fonte que persista a escrita, como um banco de dados, arquivo em disco, api, etc.
O método DELETE
Agora vamos finalmente para o DELETE.
Como vocês já perceberam, o delete será algo em simples de escrever, pois utilizaremos os mesmos princípios do PUT.
app.delete('/:id', (req, res) => { const item = findItem(req.params.id); // deletar o item return res.json({}); });
Esse comentário que eu adicionei escrito “deletar o item” é porque, como não estamos utilizando uma fonte que persista escrita, não estamos de verdade deletando o item do nosso array de dados.
Conclusão
Esse foi um post bem simples, dedicado inteiramente aos iniciantes e tem o intuito de mostrar como as coisas funcionam. Acredito que esse post tenha te dado um entendimento de como funcionam as APIs REST, porém ainda tem muito pra aprofundar, existe ainda uma infinidade de coisas que não falei, como por exemplo, tratamento de erros, validação, response codes, autenticação, autorização, rotas, versionamento de api, etc.
Uma verdadeira infinidade de coisas a serem ditas.
Se o pessoal realmente gostar desse tipo de post e quiser que eu continue com esse projeto exemplo, eu posso fazer a parte 2, implementando mais um pouco das coisas que mencionei.
Se você leu até aqui, deixe um comentário com a hashtag #curtidemais se você gostou #naocurti se você não gostou.
Dever de casa
Se você leu todo o post, significa que você está mesmo interessado em aprender NodeJS. Então vou deixar aqui o dever de casa para você.
1 – Na função findItem
, dentro do método find
, eu estou usando ==
e quero que você faça funcionar com ===
.
(dica: isso vai requerer que você altere o tipo de dado).
2 – No método app.get('/', () => {} )
eu estou retornando os dados estáticos com um objeto que contém name e instagram, altere esse método para retornar o nosso array de dados.
3 – Opcional: Coloque esse projeto no seu Github e poste uma foto nos stories do seu Instagram e me marque lá @emersonbrogadev.
(dica: se não souber usar Git ou Github, assista os seguintes vídeos Tutorial Git em 20 minutos e Tutorial Github em 20 minutos)
Obrigado pela leitura. Compartilhe!
Se você gostou desse post, compartilhe com seus amigos, ajude a espalhar conhecimento!
- Faça parte da nossa lista de Desenvolvedores
- Veja as dicas no Instagram
- Se inscreva em nosso canal do Youtube
- Curta nossa página no Facebook
- Não perca as atualizações no Twitter
- Siga nossos repositórios no Github
9 Comments
Everton Coutinho · 2020-02-19 at 11:41
#curtidemais Muito bom, estou começando a estudar APIs agora, estudo Java e JS
Ednilson · 2020-03-06 at 08:14
#curtidemais
Douglas Engratules · 2020-05-01 at 13:52
#top
Bem resumido e bem didático, continue assim
Amanda · 2020-05-03 at 11:47
Olá Emerson muito bom o artigo o/. Estou iniciando nessa jornada e estou fazendo esse curso, muito bom por sinal, o que você acha? Aceito mais recomendações, quanto mais melhor, conhecimento nunca é demais rs
http://tiny.cc/programdorfullstack
Feliciano Carlos Gomes · 2020-05-13 at 09:39
Ótimo artigo, muito útil para quem está começando e quer ter uma noção se como as coisas funcionam.
Leonardo · 2020-05-13 at 15:33
#curtidemai
Emerson Pessoa · 2020-06-03 at 14:51
#curtidemais
Adenilson Brito Dos Santos · 2020-06-17 at 17:36
#CurtirDeMais
Arlindo Viana · 2021-01-04 at 10:28
#curtidemais