Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Notes API — Node.js

Node.js Express JWT Jest License

API REST de notas con autenticación por JWT, escrita en Node.js + Express puro, sin ningún framework de frontend alrededor. Es el hermano Node de los otros dos backends del portfolio (Java/Spring y Python/FastAPI), con un dominio distinto (notas con etiquetas) para que no sea el mismo proyecto reescrito tres veces.

¿Qué hace esto?

CRUD de notas por usuario autenticado, con etiquetas y búsqueda:

Método Ruta Descripción
POST /api/auth/register Registro de usuario
POST /api/auth/login Login, devuelve JWT
GET /api/notes Lista paginada de notas del usuario, con filtros ?tag= y ?search=
POST /api/notes Crear nota (title, body, tags[])
GET /api/notes/:id Ver una nota propia
PUT /api/notes/:id Actualizar una nota propia (reemplaza sus etiquetas)
DELETE /api/notes/:id Eliminar una nota propia

Todas las rutas de /api/notes requieren Authorization: Bearer <token>. Pedir una nota que no existe o que pertenece a otro usuario devuelve 404 en los dos casos — nunca 403 para la segunda, porque distinguirlas confirmaría que el ID pertenece a otra persona.

Arquitectura

src/
  db/            → conexión SQLite (node:sqlite) y schema.sql
  repositories/   → único lugar con SQL: users, notes + tags (tabla de unión)
  services/       → reglas de negocio: validación, hashing, propiedad de recursos
  controllers/    → traducen HTTP <-> llamadas a los servicios
  routes/         → definición de endpoints
  middleware/     → requireAuth (verifica JWT), errorHandler (centraliza errores)
  app.js          → ensambla todo con inyección manual de dependencias
  server.js       → punto de entrada real (lee .env, abre la DB, arranca Express)

app.js recibe la conexión a base de datos como parámetro en vez de importar un singleton — eso es lo que permite que los tests levanten una base de datos en memoria distinta por archivo de test, sin tocar ningún fichero en disco.

Cómo ejecutarlo

git clone https://github.com/Nicolas-Silva-Cremona/notes-api-nodejs.git
cd notes-api-nodejs
npm install
cp .env.example .env

npm start          # arranca en http://localhost:3000
npm run dev         # igual, pero reinicia solo al guardar (node --watch)
npm test            # 14 tests con Jest + Supertest

Prueba rápida con curl:

curl -X POST localhost:3000/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{"email":"demo@example.com","password":"password123"}'

# usa el token devuelto:
curl -X POST localhost:3000/api/notes \
  -H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
  -d '{"title":"Comprar leche","tags":["recados"]}'

Decisiones técnicas

  • node:sqlite en vez de better-sqlite3 o pg: es el módulo SQLite integrado en Node (estable desde Node 22). Para esta API no hace falta levantar un servidor de base de datos aparte ni compilar un binding nativo al hacer npm install — el repo se clona y funciona. El coste es fijar "engines": {"node": ">=22.5.0"} en package.json.
  • Etiquetas en tabla propia (tags + note_tags), no una columna de texto separada por comas: permite filtrar por etiqueta con un JOIN indexado y evita el problema clásico de "¿case-sensitive? ¿espacios? ¿cómo busco una nota con dos etiquetas a la vez?" que arrastra el string separado por comas.
  • 404 en vez de 403 al acceder a una nota de otro usuario: devolver 403 confirmaría que el ID existe pero no es tuyo, filtrando información. noteService.getOwned trata "no existe" y "no es tuya" exactamente igual.
  • Mismo mensaje de error para email inexistente y contraseña incorrecta en el login: distinguirlos permite a un atacante enumerar qué emails están registrados probando contraseñas al azar.
  • Inyección de dependencias manual, sin contenedor: app.js construye a mano repository -> service -> controller -> route. Para el tamaño de este proyecto, un contenedor de DI sería una capa de indirección sin beneficio real; pasar db como parámetro ya es suficiente para poder testear con una base de datos en memoria.

Licencia

MIT. Ver LICENSE.

About

API REST de notas con Express, JWT y SQLite (node:sqlite), con tests de integración.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages