API em Node.js com Express e PostgreSQL para cadastro de usuarios e tipos de usuario.
- Node.js
- Express
- PostgreSQL
- pg
- dotenv
- morgan
Instale as dependencias:
npm installCrie o arquivo .env na raiz do projeto:
PORT=7777
DATABASE_URL=postgres://usuario:senha@localhost:5432/nome_do_bancoCrie as tabelas no banco usando o arquivo:
src/database/schema.sql
Inicie a API:
npm startPara desenvolvimento:
npm run devPor padrao, a API roda em:
http://localhost:7777
src/
app/
controllers/
database/
models/
routes/
O fluxo usado no projeto e:
routes -> controllers -> models -> database
Base da rota:
/tipo-usuario
GET /tipo-usuarioResposta:
[
{
"id_tipo": 1,
"tipo": "admin"
}
]GET /tipo-usuario/1Resposta:
{
"id_tipo": 1,
"tipo": "admin"
}POST /tipo-usuarioBody:
{
"tipo": "admin"
}Resposta:
{
"id_tipo": 1,
"tipo": "admin"
}PUT /tipo-usuario/1Body:
{
"tipo": "medico"
}PATCH /tipo-usuario/1Body:
{
"tipo": "enfermeiro"
}DELETE /tipo-usuario/1Quando remove com sucesso, retorna 204 No Content.
Se o tipo estiver sendo usado por algum usuario, a API retorna erro, porque existe chave estrangeira entre usuarios.tipo e tipo_usuario.id_tipo.
Base da rota:
/users
GET /usersResposta:
[
{
"id_user": 1,
"nome_usuario": "Guilherme",
"tipo": 1,
"tipo_usuario": "admin",
"status": "ativo"
}
]GET /users/1Resposta:
{
"id_user": 1,
"nome_usuario": "Guilherme",
"tipo": 1,
"tipo_usuario": "admin",
"status": "ativo"
}POST /usersBody:
{
"nome_usuario": "Guilherme",
"senha": "123456",
"tipo": 1,
"status": "ativo"
}O campo tipo pode receber o ID do tipo de usuario. O status e opcional; se nao for enviado, entra como ativo.
PUT /users/1Body:
{
"nome_usuario": "Guilherme Souza",
"senha": "123456",
"tipo": 1,
"status": "ativo"
}PATCH /users/1Body:
{
"status": "inativo"
}DELETE /users/1Quando remove com sucesso, retorna 204 No Content.
Base da rota:
/api/noticias
GET /api/noticias/principalPOST /api/noticias/principalBody:
{
"titulo": "Titulo da noticia",
"resumo": "Resumo sobre a noticia",
"imagem": "url_do_banner",
"conteudo": "Conteudo completo"
}GET /api/noticias/secundarias?limite=4&pagina=1POST /api/noticias/secundariasBody:
{
"resumo": "Resumo sobre a noticia",
"imagem": "url_thumbnail",
"link": "/noticia/1"
}PUT /api/noticias/secundarias/1DELETE /api/noticias/secundarias/1GET /api/noticias?pagina=1&por_pagina=10POST /api/noticiasBody:
{
"titulo": "Titulo da noticia",
"resumo": "Resumo da noticia",
"banner": "url_do_banner",
"conteudo": "Conteudo completo em HTML",
"categoria": "diaria"
}PUT /api/noticias/1PATCH /api/noticias/1Body:
{
"resumo": "Atualizar apenas o resumo"
}DELETE /api/noticias/1Quando remove com sucesso, retorna 204 No Content.
Base da rota:
/api/course-page
POST /api/course-pageO body segue o payload completo definido no Notion, com blocos como hero, overview, featuredCourse, learningPath, secondaryCourses e cta.
GET /api/course-pageResposta:
{
"success": true,
"data": {
"id": 1,
"hero": {},
"overview": [],
"featuredCourse": {},
"learningPath": {},
"secondaryCourses": [],
"cta": {}
}
}PUT /api/course-page/1PATCH /api/course-page/1Body:
{
"hero": {
"title": "Novo titulo do hero"
}
}DELETE /api/course-page/1Resposta:
{
"success": true,
"message": "Pagina removida com sucesso"
}Base da rota:
/api/courses
POST /api/coursesBody:
{
"title": "Primeiros Socorros Basicos",
"description": "Curso introdutorio de emergencia.",
"thumbnail": "/uploads/thumb1.png",
"status": "Publicado",
"duration": "2h",
"level": "Iniciante"
}GET /api/coursesGET /api/courses/1PUT /api/courses/1Body:
{
"title": "Primeiros Socorros Avancado",
"status": "Rascunho"
}DELETE /api/courses/1Quando remove com sucesso, retorna 204 No Content.
Alguns exemplos de erro:
{
"message": "id de usuario invalido"
}{
"message": "Dados invalidos",
"erros": [
"nome_usuario e obrigatorio",
"senha e obrigatoria",
"tipo e obrigatorio"
]
}{
"message": "tipo informado nao existe"
}Tabelas usadas:
CREATE TABLE IF NOT EXISTS tipo_usuario (
id_tipo SERIAL PRIMARY KEY,
tipo VARCHAR(15)
);
CREATE TABLE IF NOT EXISTS usuarios (
id_user SERIAL PRIMARY KEY,
nome_usuario VARCHAR(100),
senha TEXT,
tipo INT,
status VARCHAR(15),
FOREIGN KEY (tipo) REFERENCES tipo_usuario(id_tipo)
ON UPDATE CASCADE
ON DELETE RESTRICT
);
CREATE TABLE IF NOT EXISTS noticias (
id_noticia SERIAL PRIMARY KEY,
titulo VARCHAR(150),
resumo TEXT NOT NULL,
imagem TEXT,
banner TEXT,
conteudo TEXT,
link TEXT,
categoria VARCHAR(20) NOT NULL DEFAULT 'diaria',
data DATE NOT NULL DEFAULT CURRENT_DATE
);