Clase 3

Jueves Mañana, 2026, Primer Cuatrimestre

Temario

  • REST
  • Redes e Internet.
  • Cualidades de diseño y principios SOLID (mención).
  • Frontend y Backend (repaso).
  • Arquitectura lógica en capas: Services. Controllers. Repositories (repaso)
  • Promises: Mención
  • Manejo de errores
  • Testing. Introducción. Conceptos generales. Estrategias. BDD. TDD.
  • Frameworks Web MVC. Livianos y pesados. Ejemplos. Cómo se estructura el servidor (backend).

Resumen

Repaso de la clase pasada

Repasamos lo visto la clase pasada y dejamos materiales complementarios:

  • 🌐 Internet y Redes: https://howdns.works/es/
  • Herramientas:
    • Exposición HTTP con Express:
    • ⚠️ Ojo, hoy en día otra herramienta común para construir interfaces Web y APIs es next.js, pero en la materia sólo usaremos express para la exposición HTTP. Ocasionalmente nextjs aparecerá en ejemplos, pero con un uso limitado.
  • 🐋 Docker: es una herramienta opcional. Si tenés curiosidad, acá dejamos un tutorial
  • Concurrencia en node.js: el elemento central de planificación en las aplicaciones node es el event loop, que permite la programación concurrente aún con un sólo proceso y un sólo hilo (si utilizaste poll, epoll o select en Sistemas Operativos quizás no te resulte una idea tan novedosa). Podés encontrar más información sobre su funcionamiento en el sitio de la electiva Arquitecturas Concurrentes y en MDN
  • Axios: aún es pronto para ponerse a trabajar con esta herramienta en profundidad (primero nos concentraremos en exponer APIs HTTP/REST antes que en consumirlas), pero acá dejamos su documentación en español
  • Express vs node: node es un entorno de ejecución, que además de un intérprete y un gestor de paquete cuenta con bibliotecas de bajo nivel. Si bien node permite nativamente programar aplicaciones TCP/HTTP, para programar aplicaciones HTTP/REST es más conveniente utilizar un framework de alto nivel que nos simplifique varias tareas y nos provea de un marco de trabajo para definir rutas.
  • JSON: es un formato basado en texto plano que sirve para representar datos estructurados. MDN nos da una breve introducción. A diferencia de otros lenguajes de metadatos similares como XML y YAML, JSON se inspira en la sintaxis de objetos de JavaScript, que sigue la estructura { "clave": "valor" }.
  • CURL: es un cliente HTTP de línea de comandos, útil para usarlo como parte de scripts. Sin embargo para desarrollar y probar APIs te puede resultar útil Postman.

Proceso de desarrollo

  • Desarrollo iterativo-incremental: este concepto ya lo deberían tener de materias anteriores. Si no, acá dejamos una breve introducción y comparación con otros enfoques. En esta materia, siempre asumiremos que trabajamos bajo ese enfoque.
  • Justamente, porque el software mutará todo el tiempo, es fundamental trabajar con herramientas de control de versiones, como git, y también con herramientas que permitan dar seguimiento a los problemas y propuestas de mejora que surgen: los issue trackers, como por ejemplo Github Issues y Github Projects (dos herramientas que nos acompañarán en el trabajo práctico). Hay muchísimas alternativas, como Jira o Trello (también un servicio en la nube) y Bugzilla y Mantis (herramientas de código abierto que se pueden instalar localmente)
  • Todas estas etapas son esenciales no sólo para dar soporte a la codificación del proyecto, sino también a la planificación, análisis y prueba.

Desarrollo Backend

Redes (de nuevo)

Ya mencionamos HTTP (y su variante encriptada, HTTPS): se trata de un protocolo omnipresente en el mundo de internet (y en particular, la Web, su servicio de páginas). Está basado en texto plano, no tiene estado (es stateless), y sus elementos fundamentales son los pedidos HTTP, que tienen métodos, rutas, parámetros (opcionales), cuerpos (opcionales) y cabeceras de (pedido y respuesta, también opcionales).

Sobre HTTP se monta REST, que podemos pensarlo tanto como un protocolo de más alto nivel, como simplemente un conjunto de convenciones y buenas prácticas sobre el uso de HTTP, como por ejemplo que los pedidos de tipo DELETE serán utilizados para eliminar información, mientras que aquellos de tipo GET sólo se usarán para acceder información de forma idempotente.

Otro elemento importante de REST es la orientación a recursos, que plantea que las rutas HTTP no representan acciones sino contenidos organizados en una estructura arbórea que podemos consultar y operar. No será el foco de la materia aprender las convenciones de REST (tema que si se tratará en mayor profundidad en DDSi), pero sí comenzar a reconocer sus estructuras básicas. A quien quiera saber más le recomendamos consultar la sección sobre REST del Tutorial HTTP, o el libro RESTful Web Services Cookbook de Subbu Allamaraju.

Arquitectura lógica

Cuando hablamos de arquitectura nos encontraremos con múltiples definiciones e interpretaciones. Una de ellas es la arquitectura física, que ya trabajamos, que habla de la disposición (despliegue) de nuestros componentes software a lo largo de los distintos modos de una red.

Pero también podríamos hablar de la arquitectura lógica: el diseño de más alto nivel de nuestros componentes software. All´i estudiaremos como los módulos, paquetes, clases e interfaces se organizan en torno en agrupaciones de alto nivel, que comparten tecnológicas, estilos de comunicación, equipos de trabajo, heurísticas o formas de trabajo.

Tal como existe una gran variedad de arquitecturas físicas, también existen muchos tipos de arquitecturas lógicas, también llamados estilos arquitectónicos o patrones arquitecturales (o cualquier combinación similar de estos términos 😛). Cada una ya tiene sus propias ventajas y desventajas, detractores y defensores, y no son necesariamente antagónicas. Además, cada una buscan resolver un cierto problema del sistema, por que en ocasiones podemos verlas complementándose. Por ejemplo, en el mundo del desarrollo Web tenemos dos problemas típicos:

  • ¿Cómo exponer las funciones del Backend hacia el mundo exterior? ¿Cómo lidiar con los problemas de presentación bajo las limitaciones de la arquitectura física web? ¿Cómo organizar los componentes en el cliente?
    • MVC Web del lado del servidor: Inspirado en el patrón Model-View-Controller de los años 80, adaptado a aplicaciones web. La lógica del servidor está dividida en controladores (que manejan la interacción del usuario), modelos (que representan los datos y lógica de negocio), y vistas (que generan las respuestas HTML o datos). Ejemplo clásico: aplicaciones con Ruby on Rails o Django.
    • MVC (y derivados MVP, MVVM) Web del lado del cliente: cuando se utiliza un cliente pesado, el patrón MVC puede migrar al navegador. Frameworks como React (aunque no implementa MVC estrictamente), Angular o Vue ofrecen formas de organizar el código del cliente con separación entre lógica, datos y presentación.
  • ¿Cómo coordinar internamente los componentes del Backend? ¿Cómo vincular las reglas de negocio, la persistencia de la información y la exposición hacia el mundo exterior?
    • Modelo basado en concerns (incumbencias): organiza el backend en grupos de componentes lógicos como Presentación, Dominio, y Persistencia. Esta separación permite un mayor desacoplamiento y extensibilidad, alineándose muchas veces con prácticas de diseño orientadas a dominio (como DDD).
    • Modelo en capas: típicamente incluye capas como Controladores, Servicios, Repositorios y Modelos, y utiliza DTOs para la transferencia de información. Leer el capítulo 4 del Libro Domain Driven Design de Eric Evans (ver materiales).
    • Modelo orientado a objetos (OO): no es un patrón arquitectónico per se, pero se integra bien con los anteriores. Apunta a modelar el dominio a partir de un conjunto de objetos que colaboran sin una estructura a-priori, sino guiada por los requerimientos. En los mundos de MVC o la separación en base a concerns, el modelo puede estar organizando en torno a un dominio de objetos sin otra estructura particular.

Ninguna arquitectura es “la mejor” en forma absoluta. Cada una tiene ventajas y limitaciones, y su elección dependerá del tipo de aplicación, el equipo, las tecnologías disponibles y los requerimientos del negocio.

Paréntesis: dominio, “modelos”, y modelo rico vs anémico

Tomamos como ejemplo este modelo de dominio sencillo:

classDiagram
  Carrito --> Item
  Item --> Producto

image

Acá estamos viendo dos cosas:

  • Por un lado, el (modelo) de dominio del negocio: los conceptos y sus vínculos, desde un punto de vista analítico
  • Pero también estamos viendo una propuesta de como bajar esos conceptos a un ambiente de objetos, usando clases.

⚠️ Intencionalmente no estamos mostrando el comportamiento; ya vamos a eso.

Esto se puede bajar a JS de la siguiente forma:


class Item {
  constructor(producto, cantidad) {
    this.producto = producto
    this.cantidad = cantidad
  }
}

class Carrito {
  constructor() {
    this.items = []
  }

  agregarProducto(item) {
    this.items.push(item)
  }
}

class Producto {
  constructor(titulo) {
    this.titulo = titulo
  }
}

let gaseosa = new Producto("Lima Limon Generica")

let carrito = new Carrito()
carrito.agregarProducto(new Item(gaseosa, 2))

Pero ahora pensemos: ¿dónde podríamos ubicar el comportamiento del “calcular el precio total del carrito”?

// La respuesta de PDP / DDSi / arquitecturas orientadas a objetos / incumbencias / guiadas por el dominio es trivial:
carrito.precioTotal() // ponemos ese comportamiento en el objeto del modelo de dominio

// La otra opción (por ejemplo, en arquitectura lógica de capas)
// es NO poner el comportamiento en el objeto de dominio sino en otro componente que no es parte del dominio: un servicio
servicioDeCarritos.precioTotalDe(carrito)
// o incluso
servicioDePrecios.precioTotalDe(carrito)


// lo que me interesa es que el modelo queda SIN comportamiento interesante (modelo anémico) y las clases se vuelven
// prácticamente estructuras de datos.

Corolario: el significa de dominio / modelo de domino varía según el contexto en termino de análisis: SIEMPRE hay un modelo de dominio en términos de implementación / diseño / programación: son los componentes software (objetos) que implementan esas nociones de dominio y que pueden tener una centralidad mayor o menor según la arquitectura: modelos ricos (con comportamiento) vs modelos anémicos

Cliente liviano y pesado

  • Pesado: genera (mayormente y en su forma más naíf) genera estructuras aptas para el consumo programático (ejemplo, API REST en JSON/XML) y el cliente lo transforma en HTML.
  • Liviano: el servidor produce HTML mas o menos definitivo, el cliente hace pocas transformaciones o ninguna.

En el mundo node, express nos sirve como framework para implementar servidores para ambos estilos arquitectónicos. Frameworks como React, Vue o Angular nos servirán para implementar la lógica de presentación en el cliente en el contexto de un cliente pesado.

Errores

Como manejarlos y dónde.

  • Excepciones
  • “Capas” superiores / Presentación

Material

Tarea

Si no lo hiciste ya:

Además:

  • ¡No te olvides de asistir a la próxima clase de los sábados!