Promesas Valencia (2): Por qué Rust y qué stack web

Publicado el 18/06/2026

Aprender con un proyecto de verdad

Este proyecto tiene una doble agenda: además de la utilidad cívica (entrada 1), es un vehículo para aprender Rust. Y aprender de verdad, no con ejercicios de juguete, sino construyendo una aplicación web completa que tiene que desplegarse, hablar con una base de datos, procesar texto, llamar a modelos de IA y aguantar reinicios sin romperse.

¿Por qué Rust para esto? Precisamente porque es exigente. Obliga a pensar en los errores (no hay excepciones que ignorar: o manejas el Result o no compila), en quién es dueño de cada dato, y en los estados imposibles antes de que ocurran. Es un lenguaje que devuelve el favor del esfuerzo: cuando compila, suele funcionar. Para alguien que quiere subir de nivel, esa fricción es el objetivo, no el obstáculo.

El stack, pieza a pieza

La regla que nos marcamos: stack fijado, no cambiar sin motivo. Elegir bien una vez y construir encima, en lugar de reabrir decisiones cada semana. Estas son las piezas y el porqué de cada una.

Capa Elección Por qué
Web Axum 0.8 El framework de referencia del ecosistema Tokio: ergonómico, con un sistema de extractors que encaja con el tipado de Rust.
ORM SeaORM 1.1 ORM async maduro; con rustls evitamos depender de OpenSSL del sistema.
BD PostgreSQL 16 Sólido, conocido y externo (la app no lo gestiona).
Plantillas Askama 0.13 Plantillas verificadas en tiempo de compilación: si una variable no existe, no compila. Se incrustan en el binario.
CSS Tailwind 3.4 Estilos sin salir del HTML; el CSS final solo contiene las clases usadas.
Async tokio El runtime async estándar de facto.
Auth tower-sessions + argon2 Sesión por cookie + hash de contraseñas como debe ser.

La decisión más característica de Rust aquí es Askama: que un fallo de plantilla sea un error de compilación, no un 500 en producción, es exactamente el tipo de garantía por la que se elige este lenguaje. Cada vez que se toca una plantilla hay que recompilar —incomodidad menor— a cambio de que las vistas no mientan nunca sobre los datos que reciben.

Convenciones que se ganan el sueldo

Algunas decisiones pequeñas que ahorran problemas a diario:

  • Todo en español: identificadores, comentarios, textos de la interfaz. El proyecto es sobre un municipio español; el código habla su idioma.
  • Vista ≠ modelo: nunca se pasa una entidad de la base de datos directamente a la plantilla. Se mapea a una struct de vista que ya trae las fechas formateadas, las etiquetas y hasta las clases CSS resueltas. La plantilla solo pinta.
  • Tipos y estados como texto + enum de apoyo: el tipo y el estado de una promesa se guardan como texto en la base de datos, pero con un enum en Rust que centraliza los valores válidos, sus etiquetas y sus colores. Nada de cadenas «mágicas» sueltas por el código.
  • Errores con un solo tipo: los handlers devuelven Result<_, AppError>, y ese error sabe convertirse en una respuesta HTTP. Un único sitio donde decidir qué se loguea y con qué código se responde.

La lección de fondo

El mayor aprendizaje no fue una librería concreta, sino interiorizar el bucle de Rust: escuchar al compilador. Buena parte de las sesiones de desarrollo consistieron en cambiar algo, dejar que el compilador señalara todo lo que ese cambio rompía, e ir resolviéndolo punto por punto. Es lento al principio y liberador después: refactorizar deja de dar miedo cuando el compilador es tu red de seguridad. Ese cambio de mentalidad —de «espero que funcione» a «el tipo lo garantiza»— es, probablemente, lo que más se llevará uno de aquí.