← Node.js: JavaScript fuera del navegador

UD5 · Guía y taller práctico

Lo que debes recordar

El método

Cómo se monta un servicio
  1. ¿Qué datos hay, y dónde viven?
  2. ¿Qué reglas tienen, sin pensar todavía en HTTP?
  3. ¿Qué se puede pedir desde fuera, con qué método y qué ruta?
  4. ¿Qué responde cada caso, incluidos los que fallan?
  5. ¿Qué queda registrado, y qué no debe salir nunca?

La idea más importante

Escríbelo a mano una vez. Después usa el framework sabiendo qué te está resolviendo.

Vale para Express hoy y para Spring Boot el año que viene. Un framework es un conjunto de respuestas a problemas concretos; si no conoces los problemas, sus respuestas son magia, y la magia no se puede depurar.

Su elemento complementario, el que gobierna todo lo que viene, es este:

El servidor no se fía de nadie

Todo lo que llega de fuera —el cuerpo de una petición, un parámetro, una ruta de fichero— es sospechoso hasta que se valida. La validación del cliente es comodidad; la del servidor es la única que nadie puede saltarse.

No memorices Node

  • ¿Esto lo resuelve Node de fábrica, o necesito de verdad una dependencia?
  • ¿Este valor cambia entre máquinas? Entonces va al entorno.
  • ¿Esta operación bloquea el proceso?
  • ¿Qué pasa si el fichero no existe, o no tengo permisos?
  • ¿De quién es el fallo: 4xx o 5xx?
  • ¿Estoy devolviendo información interna en el mensaje de error?
  • ¿Quién valida esto, y qué pasa si el cliente miente?
  • ¿En qué orden se declaran mis middlewares?
  • ¿Esta ruta puede salirse de la carpeta que le corresponde?

Al terminar deberías poder responder

  1. ¿Qué es Node.js y qué desaparece respecto al navegador?
  2. ¿Qué hay en process.argv y por qué se descartan dos posiciones?
  3. ¿Por qué la configuración va en variables de entorno?
  4. ¿Qué significa un código de salida distinto de cero?
  5. ¿Qué diferencia hay entre ESM y CommonJS?
  6. ¿Qué declara package.json y para qué sirven sus scripts?
  7. ¿Qué acepta ^1.2.3?
  8. ¿Para qué sirve package-lock.json y por qué se sube?
  9. ¿Por qué no se sube node_modules?
  10. ¿Qué te preguntas antes de instalar una dependencia?
  11. ¿Por qué usamos la API de ficheros con promesas y no la síncrona?
  12. ¿Qué significa ENOENT y cómo se trata?
  13. ¿Por qué se componen las rutas con path.join?
  14. ¿Por qué se escribe en un temporal y se renombra?
  15. ¿Qué dos límites tiene un fichero JSON como almacén?
  16. ¿Qué diferencia hay entre un error esperable y uno inesperado?
  17. ¿Qué hace un servidor HTTP, paso a paso, con cada petición?
  18. ¿Qué tres cosas se escriben en una respuesta?
  19. ¿Por qué el cuerpo de la petición se lee por trozos?
  20. ¿Qué significan 200, 201, 400, 404, 405 y 500?
  21. ¿Qué dice la familia del código sobre de quién es el problema?
  22. ¿Qué es el path traversal y cómo se evita?
  23. ¿Por qué hay que enviar el tipo de contenido correcto?
  24. ¿Qué seis problemas del servidor a mano resuelve Express?
  25. ¿Qué hace express.json() y dónde se declara?
  26. ¿Qué es un middleware y qué pasa si no llama a next?
  27. ¿Cómo se distingue un manejador de errores de un middleware normal?
  28. ¿Por qué el cliente nunca debe ver una traza?
  29. ¿Cómo averiguas si un fallo es del cliente o del servidor?
  30. ¿Por qué desaparece el problema de CORS al servir todo desde el mismo origen?

El vocabulario de la unidad

Concepto Significa
Node.js Un entorno para ejecutar JavaScript fuera del navegador
Proceso El programa en ejecución, con sus argumentos y su entorno
Variable de entorno Configuración que vive fuera del código
Código de salida El número con el que termina un programa: 0 es éxito
ESM / CommonJS Los dos sistemas de módulos: el estándar y el heredado
package.json La ficha del proyecto: scripts y dependencias
Versionado semántico Mayor, menor y parche, y qué compatibilidad implica cada uno
Fichero de bloqueo El registro de las versiones exactas instaladas
Operación síncrona La que bloquea el proceso hasta terminar
ENOENT Código de error: no existe el fichero o la carpeta
Escritura atómica Escribir en un temporal y renombrar, para no dejar datos a medias
Puerto El número por el que un servidor escucha
Petición / respuesta Lo que envía el cliente / lo que devuelve el servidor
Código de estado El número que resume qué ha pasado con la petición
Estático Archivo servido sin transformación desde el disco
Tipo de contenido La cabecera que dice qué es lo que se envía
Path traversal Salirse de la carpeta permitida con tramos de ruta
Framework Un conjunto de soluciones a problemas repetidos
Middleware Un paso de la cadena por la que pasa cada petición
Manejador de errores El middleware de cuatro parámetros que decide qué se responde
Traza El detalle técnico de un error: para el registro, no para el cliente

La siguiente unidad

Ya tienes un servidor que sirve tu web y responde a algunas rutas. Lo que todavía no tienes es una API diseñada.

Lo que falta
  1. Rutas sueltas
  2. Recursos y contrato
  3. Capas y persistencia
  4. Cliente y servidor, de punta a punta

En la UD6 tus rutas dejarán de ser una colección de casos y pasarán a ser el diseño de un recurso: el CRUD completo, la separación en capas, un contrato de errores estable, la web servida y consumiendo su propia API, y la configuración y las comprobaciones que hacen falta para poder publicarlo. Cierra el módulo, y deja el camino hecho para el módulo de servidor.

Ya deberías ser capaz de

  • Explicar qué es Node.js y en qué se diferencia el entorno del navegador del de un servidor.
  • Ejecutar programas desde la terminal y leer argumentos y variables de entorno.
  • Organizar un proyecto con package.json, scripts y dependencias declaradas.
  • Instalar dependencias entendiendo el versionado semántico y el fichero de bloqueo.
  • Leer y escribir ficheros con la API de promesas, componiendo rutas de forma portable.
  • Usar un fichero JSON como almacén sin corromperlo.
  • Levantar un servidor HTTP con el módulo nativo y responder con el código de estado correcto.
  • Servir ficheros estáticos resolviendo su tipo de contenido y protegiendo las rutas.
  • Explicar qué problemas resuelve Express y reescribir el servidor nativo con él.
  • Escribir middleware propio, registrar las peticiones y centralizar el tratamiento de errores.