Apéndice C — C. El mapa universal

Qué vive en el lenguaje, qué en el framework, qué en la industria

NotaEn una frase

La tabla de tres columnas con todos los conceptos del libro clasificados — ahora con evidencia en los tres stacks. Cuando cambies de stack, la columna derecha es tu equipaje completo; las otras dos son solo sintaxis nueva.

C.1 El mapa completo

Concepto Del lenguaje Del framework De la industria (te lo llevas) Cap.
Async/concurrencia event loop / asyncio / goroutines — I/O-bound se paraleliza, CPU-bound no 20
Tipos en la frontera anotaciones zod / pydantic / decoder validar antes de tocar 4
Routing — Express / FastAPI / ServeMux recursos, verbos, contrato 3
Inyección de deps — Depends / closures / params construir en el borde, pedir adentro 16
Errores throw / raise / return err handler global dominio → mapper → {error:{code}} 6, 25
Auth — middleware/Depends/wrapper bcrypt, JWT corto + refresh rotado 14–18
Autorización — Depends/factory rol en la relación, ownership en la query 17
BD — pg / psycopg / pgx pool, parametrizar, tx, FOR UPDATE 10, 13
Migraciones — dbmate / alembic / goose versionadas, up+down, sin editar viejas 11
Índices/N+1 — — EXPLAIN, igualdad→orden, LIMIT 21 12
Integraciones fetch / httpx / http.Client — timeout, retry, degradación, adapter 19
Jobs — setInterval / BackgroundTasks / ticker “¿espera el usuario?” → si no, job 21
Webhooks — — firma sobre body crudo, dedupe, 200 rápido 22
Logs — pino / logging / slog JSON + request_id, nunca secretos 23
Config — dotenv / pydantic-settings / env 12-factor, fail-fast, sin defaults secretos 24
Seguridad — — OWASP auditada por endpoint, 404 vs 403 26
Testing — vitest / pytest / go test pirámide, rollback-per-test, mock en frontera 27–29
Deploy binario vs runtime — imagen única, env vars, healthcheck, migrate-gate 30–35
Versionado — — snapshot + puntero, append-only 37
Realtime — ws / WebSocket / coder auth igual que REST, rooms, LWW 38

C.2 Cómo leer la tabla

La columna derecha es el 80% del trabajo. Un senior en Node que lee Go no está “aprendiendo backend de nuevo” — está aprendiendo dónde Go pone el err y cómo se llaman sus paquetes. Las decisiones ya las tiene: parametrizar, transaccionar, auditar, testear, desplegar con compuertas.

Una transacción es un grupo de operaciones que se confirman juntas o no se confirma ninguna: transferir dinero = restar de A y sumar a B. Si falla a la mitad sin transacción, el dinero desapareció.

El framework decide menos de lo que crees. FastAPI no te obliga a usar Depends ni Express a usar middleware — pero la industria sí te obliga a validar, a autenticar una vez y a no dejar stack traces. El framework propone el mecanismo; tú mantienes el control.

Un middleware es un filtro en la cadena del request: pasa por él antes de llegar a tu handler. Auth es middleware — “verifica el token” vive una vez y protege todas las rutas, no se copia en cada una.

Un framework es un esqueleto de aplicación ya decidido: te da la estructura (rutas, validación, errores) y tú llenas la lógica. Diferencia con librería: la librería la llamas tú; el framework te llama a ti.

El lenguaje solo cambia la forma. Promise.all/gather/errgroup son la misma idea con tres acentos — como throw/raise/return err. Por eso el libro muestra los tres: para que veas que la idea sobrevive a la sintaxis.

return hace dos cosas a la vez: devuelve el resultado Y termina la función — lo que esté debajo nunca corre. return task = “aquí está el plato, salgo de la cocina”.

C.3 Mini reto

Agregar a la tabla un concepto que el libro no cubrió (ej. caché) y clasificarlo en las tres columnas.

Ejemplo resuelto — caché: del lenguaje, casi nada (quizá estructuras en memoria); del framework, un decorador/middleware opcional; de la industria: invalidar es lo difícil, medir antes de cachear, TTL + claves versionadas, Redis como pieza compartida entre instancias. Si tu fila pone “Redis” en la columna del lenguaje, vuelve al cap. 40: el producto no es del lenguaje — la decisión de cachear tampoco.

C.4 Vocabulario técnico del capítulo

Un bucle repite una acción por cada elemento o hasta cumplir una condición: for task in tasks hace algo con cada tarea. map y filter son bucles disfrazados de funciones — transforman/filtran colecciones sin for explícito.

Asíncrono = empezar algo sin esperar sentado a que termine: pides la pizza (async) y sigues trabajando; cuando llega, te avisan. Lo opuesto a síncrono (esperar parado). Vital cuando la espera es larga: red, disco, bases de datos.

Una goroutine es el hilo ultraligero de Go: go f() lanza una función en paralelo gastando casi nada — se pueden tener millones. Es la superpotencia de Go: concurrencia como palabra del lenguaje.

Un hash es una función de un solo sentido: contraseña →$2b\(10\)…`. No se puede revertir — por eso las contraseñas se hashean, no se cifran. bcrypt es lento a propósito: fuerza bruta cara para el atacante.

Una firma (HMAC) prueba que un mensaje es auténtico y no fue tocado: se calcula con un secreto sobre el contenido. Los webhooks la usan para que verifiques “esto realmente vino de Stripe”.

Un log es el diario del programa: qué pasó, cuándo, con qué request. Estructurado = en JSON con campos (request_id, user_id), para filtrar por máquina y no con los ojos.

Una variable de entorno es configuración que vive fuera del código: DATABASE_URL, JWT_SECRET. El mismo binario corre en dev y prod con distintas vars — los secretos nunca se escriben en el código.

Un secreto es un dato que no puede publicarse: contraseñas de BD, llaves de API, el secreto que firma los JWT. Viven en .env (fuera de git) o en un secret manager — nunca en el código ni en el repo.

El runtime es el motor que ejecuta tu código: Node.js es el runtime de JavaScript fuera del navegador; CPython es el de Python; Go compila a binario y el runtime va empaquetado dentro. Es “quien corre” lo que escribiste.

La memoria RAM es el escritorio de trabajo del programa: rápida, pero se borra al apagar. Los datos que deben sobrevivir van a disco o a la base de datos. Por eso let tasks = [] pierde todo al reiniciar.

El CPU es el cerebro que ejecuta instrucciones; cada núcleo puede ejecutar una cosa a la vez (por eso importan la concurrencia y los procesos paralelos). “CPU-bound” = el límite es el cálculo, no la espera.

Una base de datos es el programa que guarda datos de forma permanente y los responde rápido. Relacional (Postgres): tablas con relaciones. No relacional: documentos, clave-valor, grafos — cada una para una forma de dato distinta.

Una query es la pregunta que le haces a la base de datos en SQL: SELECT * FROM tasks WHERE done = false. La BD traduce la pregunta a un plan de búsqueda — por eso los índices importan.

Un pool es el staff de conexiones a la BD: abrir una conexión por request es caro, así que el pool mantiene ~10–20 abiertas y las presta. El request la usa, la devuelve, y la siguiente la reutiliza.

La autenticación responde “¿quién eres?” — login, contraseña, token. Se confunde con autorización (“¿qué puedes hacer?”), que es la pregunta siguiente. Primero te identificas, luego te dejan o no pasar.

Un JWT (JSON Web Token) es un token firmado: el servidor lo genera con su secreto y puede verificarlo sin consultar la BD. Ojo: está firmado, no cifrado — cualquiera puede leer su contenido, pero no modificarlo.

C.5 Lo que deberías saber hacer ahora