Full Stack Web Development
Curso orientado a entender y construir una aplicacion web completa, conectando frontend, backend, persistencia, autenticacion, APIs, pruebas, seguridad y despliegue. El objetivo no es aprender un framework concreto de memoria, sino comprender como se coordinan las piezas de una app moderna.
Desarrollo full stack significa poder razonar sobre toda la cadena de entrega: interfaz, comunicacion cliente-servidor, reglas de negocio, datos, observabilidad y operacion. Un buen perfil full stack no tiene que ser especialista maximo en cada capa, pero si entender sus contratos, dependencias y limites.
Modulo 01. Arquitectura de una aplicacion web moderna
Objetivo del modulo
Entender las capas principales de una aplicacion web moderna y las responsabilidades que deben mantener separadas para que el sistema siga siendo evolucionable.
Resultados esperados
- Explicar el papel de frontend, backend, base de datos y servicios auxiliares.
- Diferenciar renderizado, API, logica de negocio y persistencia.
- Reconocer contratos y acoplamientos entre capas.
- Entender que significa pensar una aplicacion de extremo a extremo.
Desarrollo teorico
Una aplicacion web moderna no es una sola pieza de codigo, sino un sistema formado por varias capas que colaboran. La interfaz de usuario vive en el navegador, donde renderiza componentes, gestiona estado local y reacciona a eventos. El backend expone APIs, valida entrada, ejecuta reglas de negocio y habla con bases de datos o servicios externos. Por debajo aparecen persistencia, cache, colas, almacenamiento de ficheros, observabilidad y despliegue.
Una arquitectura sana separa responsabilidades. El frontend no deberia decidir reglas criticas de negocio ni confiar ciegamente en que los datos recibidos son validos. El backend no deberia conocer detalles concretos del DOM ni asumir como se pintara una pantalla. La base de datos no es el lugar para esconder toda la logica de dominio por comodidad. Cuando esas fronteras se mezclan, la app sigue funcionando durante un tiempo, pero se vuelve mas costosa de cambiar y probar.
Monolito web frente a SPA con API
En el modelo clasico de monolito web, el servidor genera HTML completo y lo envuelve con algo de JavaScript para interactividad. En el modelo SPA (Single Page Application), el navegador recibe una aplicacion JavaScript que consume una API REST o GraphQL. Ambos enfoques son validos; la decision depende del tipo de producto, el equipo y los requisitos de rendimiento.
Un monolito web con plantillas del servidor puede ser suficiente para paneles internos o sitios con poca interactividad. Una SPA con API separada encaja mejor cuando la interfaz es rica, hay multiples clientes (web, movil, integraciones) o los equipos de frontend y backend necesitan autonomia.
Monolito web:
Navegador --> Servidor (rutas + plantillas + negocio + BD)
SPA + API:
Navegador (React/Vue) --> API REST --> Servicios --> BD
Ejemplo de contrato entre capas
El contrato entre frontend y backend se materializa en la estructura de las peticiones y respuestas. Un ejemplo tipico para un listado de tickets:
GET /api/v1/tickets?status=open&page=1&limit=20
Accept: application/json
Authorization: Bearer eyJhbGci...
HTTP/1.1 200 OK
Content-Type: application/json
{
"data": [
{
"id": "TK-1042",
"title": "Error en el login con SSO",
"status": "open",
"priority": "high",
"createdAt": "2026-03-15T10:30:00Z"
}
],
"total": 87,
"page": 1,
"pageSize": 20
}
Si el backend cambia la estructura de esta respuesta sin avisar, el frontend se rompe. Por eso el contrato debe ser explicito, documentado y versionado.
Capas tipicas y sus responsabilidades
En una aplicacion full stack moderna, cada capa tiene un papel definido:
Capa Responsabilidad principal Ejemplo
---------------------------------------------------------------------------
Frontend Renderizado, estado local, UX React, Vue, HTML/CSS
API Gateway Routing, autenticacion, rate limiting Nginx, Express
Logica negocio Reglas de dominio, validacion Servicios en Node/Python
Persistencia Almacenamiento, consultas, integridad PostgreSQL, MongoDB
Servicios aux. Email, cache, colas, ficheros Redis, S3, RabbitMQ
Observabilidad Logs, metricas, trazas Prometheus, Grafana
Ejemplo de acoplamiento inadecuado
Un error frecuente es que el backend construya respuestas pensadas para una vista concreta del frontend:
// MAL: el endpoint devuelve datos formateados para una tabla especifica
app.get('/api/dashboard-table', async (req, res) => {
const rows = await db.query(`
SELECT CONCAT(first_name, ' ', last_name) AS "Nombre completo",
DATE_FORMAT(created_at, '%d/%m/%Y') AS "Fecha",
CASE status WHEN 'open' THEN 'Abierto' END AS "Estado"
FROM tickets
`);
res.json(rows);
});
// MEJOR: el endpoint devuelve datos de dominio y el frontend formatea
app.get('/api/v1/tickets', async (req, res) => {
const tickets = await ticketService.list(req.query);
res.json({ data: tickets, total: tickets.length });
});
En el segundo caso, el backend expone datos de dominio y el frontend decide como mostrarlos. Si manana se necesita otra vista, otro cliente o un export CSV, la API sigue siendo valida.
Pensar de extremo a extremo
Disenar una aplicacion full stack significa considerar que pasa desde que el usuario pulsa un boton hasta que el resultado se persiste y se confirma. Ese recorrido atraviesa navegador, red, servidor, base de datos y vuelta. En cada paso pueden ocurrir errores, latencia o estados intermedios. Una arquitectura madura contempla todos esos puntos, no solo el camino feliz.
Contenido ampliado
- Cliente, servidor y almacenamiento.
- Monolito web frente a SPA + API.
- Acoplamiento entre capas y contratos.
Puntos clave
- Full stack significa comprender el sistema completo, no mezclarlo todo.
- Cada capa tiene una responsabilidad dominante.
- Los contratos entre capas son tan importantes como el codigo dentro de cada una.
- La complejidad aparece cuando las fronteras se difuminan.
Checklist operativa
- Identificar claramente capas y responsabilidades.
- Revisar donde se valida y donde se persiste.
- Comprobar que los contratos entre frontend y backend son explicitos.
- Evitar que una capa asuma detalles internos de otra.
Errores frecuentes
- Meter reglas de negocio importantes en el frontend.
- Acoplar la API al detalle exacto de una vista.
- Usar la base de datos como si fuera el dominio entero.
- Diseñar sin pensar en pruebas ni despliegue futuro.
Practica sugerida
Dibuja la arquitectura de una app de tickets y marca que componentes residen en navegador, backend, base de datos y servicios externos.
Preguntas de autoevaluacion
- Que responsabilidad principal tiene cada capa.
- Por que una frontera clara simplifica cambios futuros.
- Que problemas genera el acoplamiento excesivo entre frontend y backend.
Cierre
La arquitectura web moderna empieza por una idea simple: separar bien para poder evolucionar, probar y operar sin romper todo cada vez.
Modulo 02. Frontend: estructura, estado y componentes
Objetivo del modulo
Organizar la capa de interfaz con componentes reutilizables y un manejo de estado comprensible.
Resultados esperados
- Diferenciar presentacion, estado local y estado remoto.
- Entender composicion de componentes.
- Evitar props drilling y acoplamientos innecesarios.
- Diseñar UI mas mantenible.
Desarrollo teorico
El frontend moderno trabaja con componentes: piezas de interfaz que encapsulan estructura, estilo y comportamiento. Su valor no esta solo en reutilizar HTML, sino en representar partes del dominio visual con fronteras claras. Un componente de tabla, un formulario de ticket o un panel de filtros deberian tener entradas, salidas y responsabilidades entendibles.
El estado es la pieza mas delicada. Parte del estado es local de un componente, como si un modal esta abierto. Otra parte es compartida, como el usuario autenticado o los filtros globales. Otra parte es remota, como los datos recibidos de una API. Mezclar esos niveles sin criterio produce interfaces fragiles y re-renderizados innecesarios.
Composicion de componentes en React
En React, la composicion se logra mediante props y children. Un componente bien disenado recibe datos y callbacks, sin asumir nada sobre el contexto externo:
// Componente de presentacion: solo muestra datos
interface TicketCardProps {
id: string;
title: string;
status: 'open' | 'in_progress' | 'resolved';
priority: 'low' | 'medium' | 'high';
onSelect: (id: string) => void;
}
function TicketCard({ id, title, status, priority, onSelect }: TicketCardProps) {
return (
<div className={`ticket-card priority-${priority}`} onClick={() => onSelect(id)}>
<span className={`badge badge-${status}`}>{status}</span>
<h3>{title}</h3>
</div>
);
}
Estado local frente a estado compartido
El estado local vive dentro de un componente y no necesita ser visible fuera de el. El estado compartido afecta a varios componentes y debe elevarse al ancestro comun mas cercano o gestionarse con un mecanismo dedicado:
// Estado local: solo afecta a este componente
function FilterPanel({ onApply }: { onApply: (filters: Filters) => void }) {
const [status, setStatus] = useState<string>('all');
const [priority, setPriority] = useState<string>('all');
const handleSubmit = (e: FormEvent) => {
e.preventDefault();
onApply({ status, priority });
};
return (
<form onSubmit={handleSubmit}>
<select value={status} onChange={(e) => setStatus(e.target.value)}>
<option value="all">Todos</option>
<option value="open">Abiertos</option>
<option value="resolved">Resueltos</option>
</select>
<select value={priority} onChange={(e) => setPriority(e.target.value)}>
<option value="all">Todas</option>
<option value="high">Alta</option>
<option value="low">Baja</option>
</select>
<button type="submit">Filtrar</button>
</form>
);
}
Gestion de estado remoto
El estado remoto viene de una API y requiere modelar el ciclo de vida de la peticion. Un hook personalizado encapsula esta logica:
function useTickets(filters: Filters) {
const [state, setState] = useState<{
status: 'idle' | 'loading' | 'success' | 'error';
data: Ticket[];
error: string | null;
}>({ status: 'idle', data: [], error: null });
useEffect(() => {
setState((prev) => ({ ...prev, status: 'loading' }));
fetchTickets(filters)
.then((response) =>
setState({ status: 'success', data: response.data, error: null }),
)
.catch((err) =>
setState({ status: 'error', data: [], error: err.message }),
);
}, [filters.status, filters.priority]);
return state;
}
Composicion en Vue 3
Los mismos principios se aplican en Vue con la Composition API:
<script setup lang="ts">
import { ref, computed } from 'vue';
interface Ticket {
id: string;
title: string;
status: string;
priority: string;
}
const props = defineProps<{ tickets: Ticket[] }>();
const emit = defineEmits<{ select: [id: string] }>();
const searchTerm = ref('');
const filteredTickets = computed(() =>
props.tickets.filter((t) =>
t.title.toLowerCase().includes(searchTerm.value.toLowerCase()),
),
);
</script>
<template>
<input v-model="searchTerm" placeholder="Buscar tickets..." />
<ul>
<li
v-for="ticket in filteredTickets"
:key="ticket.id"
@click="emit('select', ticket.id)"
>
{{ ticket.title }} - {{ ticket.status }}
</li>
</ul>
</template>
Representar estados de carga y error en la UI
Una interfaz profesional no muestra solo el caso feliz. Debe contemplar carga, vacio y error como estados explicitos:
function TicketListPage() {
const [filters, setFilters] = useState<Filters>({ status: 'all', priority: 'all' });
const { status, data, error } = useTickets(filters);
return (
<main>
<FilterPanel onApply={setFilters} />
{status === 'loading' && <p className="loading">Cargando tickets...</p>}
{status === 'error' && <p className="error">Error: {error}</p>}
{status === 'success' && data.length === 0 && (
<p className="empty">No hay tickets con esos filtros.</p>
)}
{status === 'success' && data.length > 0 && (
<ul>
{data.map((ticket) => (
<TicketCard key={ticket.id} {...ticket} onSelect={handleSelect} />
))}
</ul>
)}
</main>
);
}
Este patron garantiza que cada estado tiene una representacion visual clara. El usuario nunca ve una pantalla en blanco sin explicacion ni un spinner eterno sin retroalimentacion de error.
Contenido ampliado
- Estado local frente a estado global.
- Props, eventos y composicion.
- Carga, error y vacio como estados explicitos de UI.
Puntos clave
- Un componente bueno tiene responsabilidad clara.
- El estado debe vivir donde aporta menos friccion y mas claridad.
- La interfaz debe representar tambien fallos y esperas, no solo el caso feliz.
- Reutilizar no significa hacer componentes gigantescos.
Checklist operativa
- Definir que datos necesita cada componente.
- Separar componentes de presentacion y componentes con logica cuando ayude.
- Modelar estados de carga y error.
- Revisar si el estado compartido esta justificado.
Errores frecuentes
- Crear componentes demasiado acoplados.
- Subir todo el estado al nivel mas alto por miedo.
- No representar vacio, error o carga.
- Mezclar fetch, render y logica de negocio sin separacion.
Practica sugerida
Diseña la estructura de componentes de una pagina de tickets con listado, filtros, detalle y formulario de alta.
Preguntas de autoevaluacion
- Que diferencia hay entre estado local y remoto.
- Cuando conviene dividir un componente.
- Por que la UI debe modelar estados de error y carga.
Cierre
Un frontend mantenible se reconoce porque cada componente y cada estado tienen un lugar lógico.
Register for free to access the remaining 10 modules, exams and certificates.
Create free accountLearning outcomes
- Explicar la arquitectura de una aplicacion web moderna de extremo a extremo.
- Diseñar frontend con estado, componentes e interaccion razonable.
- Construir backend con rutas, validacion y logica de negocio clara.
- Modelar persistencia y relaciones de datos.
- Aplicar autenticacion, autorizacion y controles web basicos.
- Integrar pruebas, observabilidad y despliegue en el ciclo de vida de la app.
Target audience
- Desarrolladores junior que quieren una vision de conjunto. - Perfiles frontend o backend que quieren entender la otra mitad del sistema. - Profesionales tecnicos que necesitan criterio sobre arquitectura web moderna.
Prerequisites
- Haber tocado al menos un lenguaje de programacion y HTML/CSS basicos. - Conocer fundamentos de JavaScript o Python ayuda mucho. - Interes por aplicaciones web y por como pasan de local a produccion.
Study guide
Guia de estudio - Desarrollo Web Full Stack
Ritmo sugerido
- Estudiar 1 modulo por sesion, prestando atencion a definiciones, comparativas y errores frecuentes.
- Tomar notas propias y resumir cada modulo en 5-10 ideas accionables.
- Dejar para el final de la sesion la practica sugerida y las preguntas de autoevaluacion.
Plan de avance
- Bloque 1: Arquitectura de una aplicacion web moderna.
- Bloque intermedio: Frontend estructura estado y componentes y siguientes para consolidar criterio.
- Bloque final: Proyecto full stack integrado y repaso transversal del resto del itinerario.
Metodo recomendado
Leer primero el objetivo del modulo, despues el desarrollo teorico, y solo entonces pasar a tabla, checklist, errores y practica. Ese orden ayuda a construir criterio antes de memorizar detalles.
Evidencias de aprendizaje
- Capacidad para explicar el modulo sin leerlo.
- Capacidad para distinguir conceptos proximos sin confundirlos.
- Capacidad para trasladar el contenido a un escenario de trabajo real.
Exam available
This course includes a 20-question exam. Register for free to access the exam and earn your digital certificate.
Create free accountGlosario - Desarrollo Web Full Stack
Function
Bloque reutilizable con entradas y salida.
Variable
Nombre asociado a un valor o estado.
API
Interfaz programatica entre sistemas o componentes.
Module
Unidad de organizacion del codigo.
Exception
Error o condicion excepcional gestionable.
Type
Categoria de dato y operaciones asociadas.
Lab / Workshop
Laboratorio o taller - Desarrollo Web Full Stack
Taller orientado a aplicar Desarrollo Web Full Stack en un escenario controlado, convirtiendo teoria en una secuencia de trabajo observable.
Pasos
- Leer el escenario y delimitar objetivo, actores y restricciones.
- Usar como apoyo los modulos: Arquitectura de una aplicacion web moderna, Frontend estructura estado y componentes, Diseno responsive y experiencia de usuario, Backend routing y logica de negocio.
- Diseñar una respuesta, configuracion, flujo o decision justificada.
- Validar riesgos, dependencias y evidencias de exito.
Evidencias esperadas
- Artefacto final usable.
- Razonamiento tecnico de las decisiones tomadas.
- Checklist de validacion o criterios de salida.
Integrative case study
Caso practico integrador - Desarrollo Web Full Stack
Una organizacion necesita mejorar o implantar capacidades relacionadas con Desarrollo Web Full Stack. Tiene restricciones de tiempo, riesgos operativos y multiples actores implicados, por lo que no basta con listar conceptos: hay que convertirlos en decisiones, artefactos y prioridades.
Entregables
- Mapa del problema y contexto.
- Propuesta de enfoque o arquitectura.
- Riesgos, dependencias y decisiones clave.
- Plan de validacion o seguimiento.
Criterios de calidad
- Coherencia tecnica con el contenido del curso.
- Claridad para priorizar y justificar decisiones.
- Aterrizaje realista en entregables y seguimiento.
Modulos especialmente utiles
- Arquitectura de una aplicacion web moderna
- Frontend estructura estado y componentes
- Diseno responsive y experiencia de usuario
- Backend routing y logica de negocio
Recursos - Desarrollo Web Full Stack
Referencias oficiales y recomendadas
Estrategia de uso de bibliografia y documentacion
Empieza por la documentacion oficial del fabricante o framework, usa despues el material del curso para consolidar el modelo mental y consulta la referencia tecnica cuando necesites comandos, configuracion o detalles operativos concretos.
Evaluation
Evaluacion - Desarrollo Web Full Stack
Preguntas abiertas de repaso
- Explica con un ejemplo por que 'Arquitectura de una aplicacion web moderna' importa dentro del curso.
- Explica con un ejemplo por que 'Frontend estructura estado y componentes' importa dentro del curso.
- Explica con un ejemplo por que 'Diseno responsive y experiencia de usuario' importa dentro del curso.
- Explica con un ejemplo por que 'Backend routing y logica de negocio' importa dentro del curso.
- Explica con un ejemplo por que 'Persistencia y modelado de datos' importa dentro del curso.
Actividades de validacion
- Comparar dos conceptos proximos del curso y justificar cuando usar cada uno.
- Redactar un mini runbook, checklist o decision memo basado en un modulo.
- Explicar a otra persona una decision tecnica o de gobierno derivada del curso.