Projeto de API Express
Habilidades utilizadas:
- Operações assíncronas utilizando callbacks;
- Operações assíncronas utilizando Promises;
- Ler e escrever arquivos localmente com NodeJS;
- Criação e consumo de funções com Promises;
- Criação de API utilizando Node e Express;
- Criação de rotas e aplicação de middlewares.
├─ README.md
├─ index.js
├─ package.json
├─ talker.json
│
├─ middlewares
│ └─ validations.js
│
└─ routes
└─ talkerRoutes.js
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());
const HTTP_OK_STATUS = 200;
const PORT = '3000';
// Raíz
app.get('/', (_request, response) => {
response.status(HTTP_OK_STATUS).send();
});
app.listen(PORT, () => {
console.log('Online');
});
const talkersRoutes = require('./routes/talkersRoutes');
app.use(talkersRoutes);
Endpoint deve retornar um array com todas as pessoas palestrantes cadastradas.
router.get('/talker', async (req, res) => {
const talkers = await fs.promises.readFile(path, 'utf-8');
return (res.status(200).json(JSON.parse(talkers)));
});
Endpoint deve retornar uma pessoa palestrante com base no id da rota. Deve retornar o status 200 ao fazer uma requisição /talker/1
, por exemplo.
router.get('/talker/:id', async (req, res) => {
const talkers = await fs.promises.readFile(path, 'utf-8');
const { id } = req.params;
const talkerById = JSON.parse(talkers).find((talker) => talker.id === parseInt(id, 10));
if (!talkerById) return res.status(404).json({ message: 'Pessoa palestrante não encontrada' });
return res.status(200).json(talkerById);
});
Endpoint retorna um token aleatório de 16 caracteres que será ser utilizado nas demais requisições. Endpoint retorna um código de status 200 com o token gerado.
router.post(
'/login',
isValidEmail,
isValidPassword,
(_req, res) => res.status(200).json({ token: '7mqaVRXJSp886CGr' }),
);
Endpoint deve ser capaz de adicionar uma nova pessoa palestrante ao seu arquivo.
router.post(
'/talker',
isValidToken,
isNameFilled,
isValidNameLength,
isValidAge,
isValidAge18yo,
isTalkDateFilled,
isValidTalkDate,
isTalkRateFilled,
isValidTalkRate,
isTalkFilled,
(req, res) => {
let talkers = fs.readFileSync(path, 'utf-8');
talkers = JSON.parse(talkers);
const { name, age, talk: { watchedAt, rate } } = req.body;
talkers.push({ name, age, id: talkers.length + 1, talk: { watchedAt, rate } });
fs.writeFileSync(path, JSON.stringify(talkers), 'utf-8'); // converte objeto JS para string JSON
res.status(201).json({ name, age, id: talkers.length, talk: { watchedAt, rate } });
},
);
Endpoint para editar uma pessoa palestrante com base no id da rota, sem alterar o id registrado.
router.put(
'/talker/:id',
isValidToken,
isNameFilled,
isValidNameLength,
isValidAge,
isValidAge18yo,
isTalkDateFilled,
isValidTalkDate,
isTalkRateFilled,
isValidTalkRate,
isTalkFilled,
(req, res) => {
const { id } = req.params;
const { name, age, talk: { watchedAt, rate } } = req.body;
let talkers = fs.readFileSync(path, 'utf-8');
talkers = JSON.parse(talkers);
const conditionIndex = (talker) => parseInt(talker.id, 10) === parseInt(id, 10);
const index = talkers.findIndex(conditionIndex);
talkers[index].name = name;
talkers[index].age = age;
talkers[index].talk.watchedAt = watchedAt;
talkers[index].talk.rate = rate;
fs.writeFileSync(path, JSON.stringify(talkers), 'utf-8'); // converte objeto JS para string JSON
res.status(200).json(talkers[index]);
},
);
Endpoint deleta uma pessoa palestrante com base no id da rota. Retorna status 204, sem conteúdo na resposta. Requisição recebe token de autenticação nos headers, no campo authorization.
router.delete(
'/talker/:id',
isValidToken,
(req, res) => {
const { id } = req.params;
let talkers = fs.readFileSync(path, 'utf-8');
talkers = JSON.parse(talkers);
const conditionIndex = (talker) => parseInt(talker.id, 10) === parseInt(id, 10);
const index = talkers.findIndex(conditionIndex);
delete talkers[index];
fs.writeFileSync(path, JSON.stringify(talkers), 'utf-8');
res.status(204).end();
},
);