Programación y habilidades digitales Node.js desarrollo backend API HTTP seguridad de API pruebas de backend

Cómo empezar con Node.js para desarrollo backend: ruta práctica

Ruta práctica para entender Node.js, construir y probar una API HTTP, validar entradas, manejar errores y preparar un despliegue seguro.

Mentor explica a una estudiante el flujo de una API backend desde las solicitudes y validación hasta los datos, respuestas y errores.
· Crezendo

Node.js permite ejecutar JavaScript fuera del navegador y usarlo para servidores, herramientas y otros procesos. No es un lenguaje nuevo ni un framework. Para aprender backend con criterio, conviene entender primero HTTP, trabajo asíncrono, validación, errores y límites de seguridad; después será más fácil evaluar cualquier framework.

Esta guía propone fases con evidencias, no un plazo para “dominar Node.js”. El proyecto central es una API de tareas con datos sintéticos y almacenamiento en memoria. Podrás comprobar su contrato y sus pruebas en tu equipo, pero no debes presentarla como una aplicación de producción: pierde los datos al reiniciar y todavía no incluye autenticación, persistencia duradera ni operación pública.

Si quieres ordenar una ruta personal o para un equipo, puedes contactar a Crezendo e indicar el nivel actual, el objetivo y el proyecto que desean practicar. El contacto solo permite consultar si existe una opción de orientación o capacitación pertinente; disponibilidad, alcance, modalidad, requisitos, fechas y costo necesitan confirmación expresa.

Antes de Node.js: la base que sí necesitas

Debes poder leer y escribir JavaScript con variables, funciones, arreglos, objetos, módulos, excepciones y promesas. También necesitas distinguir una interfaz del código que procesa reglas y datos. Si ese mapa aún no está claro, revisa las diferencias entre frontend y backend.

No es necesario dominar un framework ni una base de datos para empezar. Sí debes sentirte cómodo con una terminal, un editor, archivos JSON y un sistema de control de versiones. Practica con datos inventados y una carpeta nueva; no reutilices credenciales ni información de clientes.

Evidencia para avanzar: un script que exporta una función, la importa desde otro archivo, espera una promesa y maneja un error esperado.

Prepara un entorno reproducible

Consulta la tabla oficial de releases de Node.js y elige una edición con soporte Active LTS o Maintenance LTS. No fijamos aquí un número porque el estado de soporte cambia. Comprueba el entorno y registra la salida en el README:

node --version
pnpm --version

Inicializa una carpeta separada y conserva una estructura pequeña:

tasks-api/
├─ src/
│  ├─ app.js
│  ├─ server.js
│  └─ tasks.js
├─ test/
│  └─ tasks.test.js
├─ .gitignore
├─ package.json
└─ README.md

En package.json, declara módulos ECMAScript y scripts repetibles:

{
  "type": "module",
  "scripts": {
    "start": "node src/server.js",
    "test": "node --test"
  }
}

El lockfile debe versionarse cuando existan dependencias. No agregues paquetes por costumbre: cada dependencia ejecuta código con capacidades amplias y aumenta la superficie que debes revisar y actualizar.

Evidencia para avanzar: otra persona puede clonar la carpeta, identificar la edición soportada requerida y ejecutar los mismos scripts sin adivinar pasos.

Entiende el modelo de Node.js antes de crear rutas

Node.js ejecuta JavaScript y ofrece APIs para red, archivos, procesos y criptografía. Su biblioteca estándar favorece operaciones de entrada/salida asíncronas. Cuando una solicitud espera red o disco, el programa puede continuar atendiendo otras tareas; pero una función sincrónica larga o un cálculo pesado en el manejador puede bloquear el event loop y retrasar a todos.

El backend tampoco es una función aislada. Una transacción HTTP contiene método, URL, encabezados y, a veces, cuerpo. La respuesta contiene estado, encabezados y, opcionalmente, cuerpo. El módulo node:http expone esos elementos como streams y eventos, así que debes atender errores y limitar lo que lees.

Haz dos experimentos antes de seguir:

  1. Crea un servidor que responda GET /health con JSON y estado 200.
  2. Añade deliberadamente un cálculo largo y observa cómo retrasa otra solicitud; retíralo y documenta por qué no pertenece al manejador.

Evidencia para avanzar: diagrama cliente → solicitud HTTP → ruta → lógica → respuesta y una nota sobre qué trabajo podría bloquear el event loop.

Define el contrato de la API antes del código

La API de práctica administra tareas ficticias. Su contrato mínimo puede ser:

Solicitud Resultado esperado
GET /health 200 y estado del proceso
GET /tasks 200 y arreglo JSON
POST /tasks con título válido 201 y tarea creada
POST /tasks con JSON mal formado 400
POST /tasks con tipo de contenido incorrecto 415
POST /tasks con título inválido 422
cuerpo mayor al límite declarado 413
ruta inexistente 404
método no permitido en una ruta conocida 405 y encabezado Allow

Los códigos no son decoración. Distinguen creación, error de sintaxis, contenido no admitido, error semántico y ausencia de recurso. Mantén una forma estable para errores, por ejemplo {"error":{"code":"invalid_title","message":"..."}}, sin enviar stack traces al cliente.

Evidencia para avanzar: tabla de contrato en el README con un ejemplo de solicitud y respuesta por caso.

Separa transporte, reglas y arranque

Una estructura inicial clara evita que todas las decisiones terminen dentro de una función enorme:

  • server.js lee configuración, crea el servidor y escucha el puerto.
  • app.js decide ruta, método, estado y serialización.
  • tasks.js valida y ejecuta las reglas sobre tareas.
  • test/ comprueba reglas y contrato observable.

La validación puede empezar como una función pura:

export function normalizeTask(input) {
  if (!input || typeof input.title !== 'string') {
    return { ok: false, code: 'invalid_title' };
  }

  const title = input.title.trim();
  if (title.length < 1 || title.length > 120) {
    return { ok: false, code: 'invalid_title' };
  }

  return { ok: true, value: { title, completed: false } };
}

Validar implica forma y significado. Un texto puede ser JSON válido y aun así no cumplir las reglas. Rechaza campos inesperados si el contrato no los admite; nunca mezcles directamente un objeto recibido con un registro interno.

Evidencia para avanzar: app.js no conoce cómo se valida un título y tasks.js no conoce objetos HTTP.

Lee el cuerpo como dato no confiable

El cuerpo de una solicitud llega como stream. Acumularlo sin límite permite consumir memoria. Antes de analizar JSON:

  1. acepta solo el tipo de contenido declarado por el contrato;
  2. cuenta bytes y detén la lectura al superar un límite pequeño y documentado;
  3. captura errores de stream;
  4. trata el fallo de JSON.parse como solicitud inválida;
  5. valida tipo, longitud, formato y regla de negocio;
  6. registra el tipo de fallo, no el contenido sensible recibido.

OWASP recomienda validar temprano toda entrada no confiable y aplicar límites de tamaño. La validación reduce errores, pero no sustituye autorización, consultas parametrizadas, cifrado de transporte ni controles de abuso.

Evidencia para avanzar: pruebas negativas para JSON roto, título vacío, tipo incorrecto, campo inesperado y cuerpo excesivo.

Maneja errores sin ocultarlos ni filtrarlos

Clasifica errores en vez de responder siempre 500:

  • Errores del cliente: contrato inválido, recurso inexistente o método no permitido.
  • Errores de dependencia: base de datos o servicio no disponible.
  • Errores inesperados: defectos que requieren correlación y diagnóstico interno.

El cliente recibe un código estable y un mensaje prudente. El log interno puede incluir marca de tiempo, ruta, estado, duración e identificador de correlación, pero no contraseñas, tokens, encabezados de autorización ni cuerpos completos. Un try/catch general sirve como última barrera; no reemplaza el manejo específico.

Atiende errores de solicitudes, respuestas y servidor. Define también qué ocurrirá cuando el proceso reciba una señal de cierre: dejar de aceptar conexiones, terminar el trabajo en curso dentro de un límite operativo y cerrar recursos.

Evidencia para avanzar: una prueba fuerza un error inesperado, obtiene una respuesta genérica y confirma que el proceso sigue disponible mediante /health.

Añade persistencia solo después de fijar el límite

El primer proyecto usa un Map en memoria. Eso permite aprender el contrato sin confundir red, base de datos y despliegue. Declara sus límites:

  • los datos desaparecen al reiniciar;
  • varias instancias no comparten estado;
  • no hay transacciones ni migraciones;
  • no existe respaldo ni recuperación.

Cuando el contrato y las pruebas estén estables, reemplaza el almacenamiento mediante una interfaz como list, findById, create y update. Así puedes probar reglas con una implementación en memoria y conectar una base después. Usa consultas parametrizadas y una cuenta con privilegios mínimos; no concatentes valores del usuario dentro de SQL.

Evidencia para avanzar: las pruebas de reglas pasan con el almacenamiento en memoria y no dependen de un servicio externo.

Configuración y secretos no son lo mismo

El puerto, el nivel de log y la ubicación de una dependencia pueden llegar mediante process.env. Valida todo al iniciar y falla con un mensaje claro si falta una configuración obligatoria. Un valor de entorno sigue siendo texto no confiable: convierte el puerto a número y comprueba su rango.

Una credencial no deja de ser sensible por estar en un archivo .env. No la subas al repositorio, no la incrustes en la imagen de despliegue y no la imprimas. En un sistema real, define creación, acceso, rotación, revocación y auditoría mediante el mecanismo seguro de la plataforma. El proyecto de práctica no necesita secretos reales.

Evidencia para avanzar: .gitignore excluye archivos locales sensibles, el README enumera solo nombres de variables y la aplicación arranca con valores de prueba no secretos.

Prueba comportamiento, no solo líneas felices

Node.js incluye node:test; node --test ejecuta los archivos de prueba y devuelve un código de salida fallido cuando corresponde. Empieza por la función pura:

import test from 'node:test';
import assert from 'node:assert/strict';
import { normalizeTask } from '../src/tasks.js';

test('rechaza un título vacío', () => {
  assert.deepEqual(normalizeTask({ title: '   ' }), {
    ok: false,
    code: 'invalid_title'
  });
});

Después crea pruebas de integración que levanten el servidor en un puerto efímero y envíen solicitudes reales. Comprueba cuerpo, estado y encabezados. Incluye concurrencia básica, cierre limpio y repetición sin estado heredado entre pruebas.

Una suite verde demuestra que esos casos pasaron en ese entorno; no demuestra ausencia de vulnerabilidades ni capacidad bajo cualquier carga.

Evidencia para avanzar: pnpm test pasa desde una copia limpia y al menos una prueba falla cuando retiras deliberadamente la validación.

Revisión de seguridad antes de exponer la API

No publiques el laboratorio por el simple hecho de que responde en localhost. Antes de una exposición real, revisa:

  • edición de Node.js con soporte LTS y proceso documentado de actualización;
  • HTTPS en el borde y comunicación protegida hasta la aplicación según la arquitectura;
  • autenticación y autorización en cada operación protegida;
  • límites de cuerpo, tiempo, concurrencia y frecuencia adecuados al riesgo;
  • validación de tipos de contenido y rechazo de métodos no admitidos;
  • CORS restringido a orígenes necesarios; CORS no reemplaza autenticación;
  • secretos fuera del código y logs, con rotación y revocación;
  • dependencias mínimas, lockfile revisado y comprobaciones de vulnerabilidades;
  • cuenta de proceso con privilegios mínimos y acceso limitado a red y archivos;
  • logs sin datos sensibles, métricas, alertas, respaldo y recuperación probados;
  • inspector de depuración deshabilitado en producción.

Los fundamentos de ciberseguridad ayudan a convertir esta lista en un modelo de amenazas y prácticas autorizadas. No inventes autenticación o criptografía para un sistema real: usa mecanismos revisados y consigue revisión especializada cuando el riesgo lo amerite.

Evidencia para avanzar: modelo de amenazas corto con activos, actores, límites de confianza, abusos posibles, controles y riesgos pendientes.

Desplegar es una decisión operativa, no una carpeta copiada

Un backend público necesita un proceso supervisado, configuración separada, terminación TLS, health checks, logs, métricas, alertas y procedimiento de reversión. La ruta /health debe indicar si el proceso puede atender, sin revelar versiones, secretos ni detalles internos. Decide por separado si la dependencia de datos está lista; una respuesta del proceso no siempre significa que toda la función de negocio lo esté.

Prueba el artefacto en un entorno controlado con datos sintéticos. Documenta variables, puerto, apagado, migraciones, respaldo y rollback. Después de desplegar, ejecuta smoke tests sobre el contrato y observa errores y latencia. La guía sobre qué es DevOps y cómo empezar amplía esta transición entre código, entrega y operación.

Evidencia para avanzar: checklist de despliegue y reversión ejecutado en un entorno no productivo. Si falta autenticación, persistencia o monitoreo, el proyecto sigue siendo laboratorio.

Convierte el proyecto en un portafolio verificable

El portafolio debe permitir que otra persona audite tu razonamiento:

  1. problema ficticio y alcance;
  2. contrato HTTP y decisiones de estados;
  3. diagrama de módulos y flujo asíncrono;
  4. código con historial de cambios;
  5. pruebas positivas y negativas;
  6. límites del almacenamiento en memoria;
  7. modelo de amenazas y controles aplicados;
  8. instrucciones reproducibles;
  9. evidencia de prueba en entorno controlado;
  10. riesgos pendientes y siguiente experimento.

No incluyas claves, capturas con datos personales, métricas inventadas ni afirmaciones de uso real. “API de laboratorio con contrato y pruebas, sin producción ni usuarios externos” es una descripción honesta. Si luego exploras una ruta profesional independiente, separa el aprendizaje técnico de las promesas comerciales y revisa cómo empezar en desarrollo web freelance en Panamá.

Cuándo incorporar un framework

Un framework puede simplificar rutas, middleware, validación y manejo de errores, pero no cambia la semántica de HTTP ni elimina las responsabilidades de seguridad. Incorpóralo cuando puedas comparar su comportamiento con el servidor básico:

  • ¿Cómo limita y analiza cuerpos?
  • ¿Cómo distingue 404, 405 y errores internos?
  • ¿Cómo se prueban rutas sin depender de un puerto fijo?
  • ¿Qué dependencias transitivas añade?
  • ¿Cómo se actualiza y se revisan avisos de seguridad?

Repite el mismo contrato con el framework elegido y conserva las pruebas. Si cambian respuestas sin decisión explícita, encontraste una diferencia que debes comprender.

Lista de salida

  • Uso una edición LTS con soporte y la verifico en la fuente oficial.
  • Puedo explicar runtime, event loop, solicitud, respuesta y stream.
  • El contrato distingue métodos, estados y errores.
  • Valido contenido, tamaño, forma y significado.
  • La lógica no depende directamente de HTTP ni de una base concreta.
  • Las pruebas cubren éxito, entradas inválidas y fallos.
  • No hay secretos ni datos reales en código, logs o portafolio.
  • El README declara límites y pasos reproducibles.
  • No llamo “producción” a un laboratorio sin controles operativos.

Aprender Node.js para backend significa construir una cadena explicable entre una solicitud y una respuesta segura. Empieza con el contrato pequeño, demuestra cada decisión con una prueba y añade complejidad solo cuando el límite anterior esté entendido.

Si deseas conversar sobre una ruta de práctica para ti o un equipo, contacta a Crezendo con los conocimientos actuales, el proyecto propuesto y la evidencia que quieren producir. Crezendo podrá confirmar si existe una alternativa pertinente y aclarar sus condiciones; el contacto no garantiza taller, cupo, certificación, despliegue, empleo ni resultado técnico o comercial.

¿Tu empresa necesita resolver este reto?

Crezendo diseña talleres a medida para empresas, ONGs y organismos de gobierno. Mira todo lo que podemos hacer por tu organización o cuéntanos tu necesidad para recibir una propuesta y cotización.

Solicitar propuesta y cotización Ver talleres para empresas