Trabalhando com JSON em requisições HTTP em node.js
Vamos supor que queremos enviar dados para o servidor, cadastrando um usuário.
Enviamos da seguinte maneira:
{
"name: "Fulano",
"email": "[email protected]"
}
Nosso servidor de exemplo atualmente se encontra assim:
import http from 'node:http'
const users = []
const server = http.createServer((req, res) => {
const {method, url} = req
if (method === 'GET' && url === '/users'){
return res
.setHeader('Content-type', 'application/json') //envio de headers do back para o front
.end(JSON.stringify(users))
}
if (method === 'POST' && url === '/users'){
users.push({
id: 1,
name: 'Fulano',
email: '[email protected]'
})
return res.writeHead(201).end()
}
return res.writeHead(404).end()
})
server.listen(3333)
Como estamos lidando com pedacinhos de código, ao lidar com JSON precisamos da informação completa, então aguardamos até que todos os pedacinhos sejam retornados e juntamos em um só. Para isso, adicionamos o seguinte código:
const buffers = []
for await (const chunk of req){
buffers.push(chunk)
}
const body = Buffer.concat(buffers).toString()
Explicando o código acima: imagine que você recebe um quebra-cabeças com várias peças, mas as peças são entregues em partes, uma de cada vez. O objetivo é montar o quebra-cabeças completo, mas você precisa primeiro coletar todas as partes antes.
Agora, vamos associar cada parte do quebra-cabeças a um pedaço de dados da solicitação HTTP:
- A matriz
buffers
é como uma mesa vazia onde você irá colocar as partes do quebra-cabeças (pedaços de dados). - O loop
for await
representa o processo de receber uma peça do quebra-cabeças de cada vez. Ele itera assincronamente pelos pedaços de dados da solicitação HTTP. - O comando
buffers.push
(chunk) é como colocar cada pedaço de dados recebido na mesa, ou seja, na matriz buffers. Cada pedaço é adicionado ao final da matriz. - Após o loop ser concluído e todas as partes (pedaços de dados) terem sido recebidas e colocadas na mesa, você tem todas as peças necessárias para montar o quebra-cabeças.
- O
Buffer.concat(buffers)
é como pegar todas as peças da mesa e juntar tudo em um único quebra-cabeças completo. - Por fim,
toString()
é como olhar para o quebra-cabeças completo e descrevê-lo em forma de texto, permitindo que você o compreenda e manipule mais facilmente.
Pronto! Já temos o nosso body
(corpo) da requisição! Mas isso não é só, pois como vimos, o body
está como texto. Se se tentarmos acessar uma propriedade, como, por exemplo,body.name
, vai retornar como undefined
Para corrigirmos esse problema, usamos um carinha muito legal chamado JSON:
const body = JSON.parse(Buffer.concat(buffers).toString())
O método JSON.parse()
analisa uma string JSON e a transforma em um objeto JavaScript. Agora quando acessamos body.name
é nos retornado Fulano
Agora podemos trocar a parte do nosso método POST:
if (method === 'POST' && url === '/users'){
const {name, email} = body
users.push({
id: 1,
name,
email,
})
return res.writeHead(201).end()
}
Agora, ao fazer uma requisição enviando os dados do usuário, agora teremos como pegar corretamente esses dados.
Porém, quando fizermos uma requisição com o método GET, não enviando nada para o body, teremos erro. Vamos contornar isso com um trycatch e adicionando o body
no nosso req:
try {
req.body = JSON.parse(Buffer.concat(buffers).toString())
} catch (error) {
req.body = null
}
E modificamos o código aqui também para pegar o corpo da requisição:
const {name, email} = req.body
Prontinho! Agora podemos lidar com JSON em nossas requisições. Até a próxima!