3 puntos por GN⁺ 2024-10-07 | 1 comentarios | Compartir por WhatsApp
  • Incluso al crear una app web pequeña con Rust, falta una experiencia integrada al estilo Django, así que la carga de unir manualmente routing, login, base de datos y herramientas de administración sigue siendo grande
  • El framework necesario debería incluir por defecto routing/handlers, plantillas, servicio de archivos estáticos, login, permisos, interfaz de base de datos, herramientas de administración, WebSockets y hot reloading
  • Existen frameworks minimalistas como actix-web y axum, y frameworks SPA como Dioxus, Leptos y Yew, pero no ensamblan por ti la configuración completa de una app web
  • Las plantillas iniciales reducen la configuración al principio, pero una vez que el proyecto se desvía, fusionar cambios y actualizar librerías sigue siendo una carga de mantenimiento
  • newt apunta a ser un toolkit web que reúne componentes existentes de forma opinada, con el objetivo de hacer que una app web pequeña pueda empezar en minutos y no en días

Un punto de partida integrado que le falta al desarrollo web en Rust

  • Incluso al hacer un proyecto web pequeño en Rust, se necesita mucho más trabajo inicial de conexión que con Django u otros frameworks similares
  • El enfoque general en la comunidad de Rust se parece más a unir por cuenta propia las piezas necesarias
    • Incluso Are We Web Yet? indica que en el desarrollo web con Rust normalmente hay que conectar las cosas manualmente y que hay que esperar trabajo adicional de configuración al comenzar
  • Este trabajo extra no es solo “un poco más”, sino que realmente hay muchos elementos que deben resolverse antes de arrancar el proyecto
  • Tener un framework web integrado haría más fácil convencer a la gente de usar Rust para apps web
    • Entre las ventajas de Rust se mencionan su sistema de tipos, el rendimiento y las pausas para café durante el tiempo de compilación

Componentes básicos que casi toda app web necesita

  • Routing/handlers

    • Hay que enviar las solicitudes entrantes al handler adecuado
    • Se deben manejar parámetros de ruta, idealmente con información de tipos
    • También conviene tener manejo de parámetros de consulta y formularios
  • Plantillas

    • Hay que generar HTML y, en algunos casos, también JSON o XML
    • Se necesita lógica básica como condicionales, match/switch y bucles
  • Servicio de archivos estáticos

    • Hay que servir recursos como CSS
    • Puede resolverse con un servidor aparte, pero para desarrollo local y despliegues pequeños resulta cómodo incluirlo en el mismo servidor web
  • Login

    • Las apps suelen tener múltiples usuarios o desplegarse en redes públicas, así que casi siempre se necesita login
    • Como conectarlo manualmente cada vez es molesto, debería poder usarse fácilmente desde el principio
    • Debe permitir personalización y opt-out
  • Permisos

    • En un sistema con varios usuarios, los datos o roles accesibles son distintos
    • Incluso un patrón check(user, object, action) puede llevar bastante lejos
  • Interfaz de base de datos

    • Se necesita una forma de almacenar los datos de la app
    • Un enfoque cercano a un ORM puede ser útil, aunque también puede haber opciones más ligeras
    • Como se usa para login, permisos y herramientas de administración, se vuelve un componente básico
  • Herramientas de administración

    • Al configurar la aplicación en local o en producción, hay que inicializar al menos un usuario o algunos datos
    • Parte de las tareas administrativas comunes debería venir incorporada para que la experiencia sea fluida
  • WebSockets

    • Permiten crear funciones que empujan datos a usuarios conectados de forma más cercana al tiempo real
  • Hot reloading

    • Los cambios en código o plantillas deberían reflejarse lo más rápido posible, así que es muy importante para la experiencia del desarrollador

Funciones adicionales necesarias para proyectos de larga vida

  • Tareas en segundo plano

    • Con el tiempo aparecen funciones que deben ejecutarse según una programación, así que tener una forma consistente de hacerlo facilita el desarrollo
  • Monitoreo/observabilidad

    • Hace falta en cualquier sistema que no sea el más pequeño y menos importante
    • Ayuda muchísimo justo cuando de verdad se vuelve urgente
  • Caché

    • Hay muchas formas de implementarlo y todas añaden complejidad; además, no siempre está claro si realmente hará todo más rápido
    • Sería bueno que el framework ofreciera algo al respecto, aunque el usuario también puede resolverlo por su cuenta
  • Correo electrónico y notificaciones

    • Si hay login, entonces por el restablecimiento de contraseña el correo puede volverse prácticamente necesario
    • Otras funciones de notificación pueden añadirse después sin gran problema
  • Herramientas de despliegue

    • Sería bueno contar con una forma consistente de desplegar a un destino específico
    • Incluso un Dockerfile autogenerado utilizable en el hosting elegido ya sería útil
  • Bundling de CSS/JS

    • Estaría bien que la herramienta web reconociera CSS y JS y los incluyera de forma natural
    • No está claro si esto necesariamente debe venir integrado

Los huecos que deja el ecosistema web actual de Rust

  • Rust ya tiene muchas herramientas para desarrollo web, pero no existe una que apunte a la experiencia integrada deseada
  • Frameworks web minimalistas

    • actix-web y axum se parecen más a frameworks pequeños como Flask o Sinatra
    • Aprovechan el sistema de tipos de Rust para ofrecer una buena experiencia de desarrollo web, pero casi no brindan funciones adicionales fuera de los handlers
    • Aunque la mayoría de proyectos puede construirse con estos frameworks minimalistas, tener que conectar cada función necesaria una y otra vez resulta molesto
  • Frameworks SPA

    • Dioxus, Leptos y Yew cubren el caso de usar Rust tanto en backend como en frontend, con WebAssembly para el renderizado del frontend
    • La experiencia de crear digital vigil con Yew fue agradable, pero no está claro si sería algo que quisiera usar en un entorno de producción real
    • Estos frameworks también son excelentes para sus propios objetivos, pero igual requieren bastante trabajo de integración
  • Conjuntos de librerías individuales

    • Hay muchas librerías para plantillas, login, permisos y WebSockets
    • Algunos proyectos y ejemplos integran ciertos componentes, pero es difícil encontrar algo que integre todas las piezas utilizadas
    • Como es un ecosistema que se mueve rápido, algunos ejemplos pueden estar desactualizados
    • “Simplemente conectarlo” termina significando investigar cómo funciona cada librería y entenderla lo suficiente

El mantenimiento que las plantillas iniciales no resuelven

  • El enfoque habitual hoy suele ser elegir un framework base como actix-web o axum, buscar las piezas necesarias, montarlas encima y conectarlas manualmente
  • Las plantillas iniciales pueden reducir el dolor al principio, pero la carga de mantenimiento permanece
    • Hay que mantener las librerías actualizadas
    • También hay que responder a cambios incompatibles (breaking changes)
    • Cuando el proyecto se aparta de la plantilla, se vuelve difícil volver a fusionar cambios de la plantilla
  • Si se operan varios proyectos, en vez de actualizar un solo framework, hay que actualizar por separado n frameworks personalizados
  • Es mejor que un framework web integral ofrezca guías de actualización entre versiones
    • Puede haber cambios incompatibles, pero al menos pueden documentarse
    • También puede reducir situaciones en las que algo falla por cambios en la interacción entre dos componentes que ni siquiera sabían que iban a integrarse entre sí

El toolkit web al que apunta newt

  • Un framework web ideal para Rust debería ofrecer las funciones mencionadas, junto con buena documentación, registro de cambios, control cuidadoso de versiones, manejo de cambios incompatibles y comunidad
  • Hoy no existe una herramienta así, y tampoco está claro si alguien más la está construyendo
  • La herramienta en desarrollo se parece más a un toolkit web que a un framework, ya que une bloques existentes de manera opinada
  • El nombre de este toolkit es nicole's web toolkit, abreviado newt
    • Está publicado en un repositorio público
    • Todavía no está en un estado utilizable, y los cambios más recientes aún no han sido publicados
    • Tampoco está listo aún para recibir contribuciones
  • El objetivo de newt es que, al crear una nueva app web pequeña, en vez de pasar días conectando piezas, se pueda empezar a trabajar en el proyecto real en cuestión de minutos
  • También hay planes de crear algunos componentes desde cero según sea necesario
    • Eso podría ser más fácil o encajar de forma más coherente
  • El ecosistema Rust necesita un estado saludable en el que existan varios toolkits de este tipo, y se espera que aparezcan otras herramientas también

1 comentarios

 
GN⁺ 2024-10-07
Opiniones de Hacker News
  • Me sorprendió que Rocket (https://rocket.rs/) no esté entre los frameworks que enumeró el autor.
    No lo he usado personalmente, y prefiero axum/actix-web, que son menos prescriptivos, pero según entiendo, el objetivo de Rocket está mucho más cerca del framework con baterías incluidas que quiere el autor, y además ya es un proyecto con bastante trayectoria.

    • Rocket fue uno de los primeros frameworks de Rust en impulsar una buena experiencia de desarrollo con macros procedurales, pero parece que perdió bastante popularidad en varias partes de la comunidad.
      Durante muchísimo tiempo necesitó nightly Rust para compilar, y eso era un gran motivo de descarte para quienes querían usar el framework en producción.
      Además, quedó atrapado durante unos 2 años en estado de release candidate de la versión 0.5.0, y la versión estable más reciente estaba muy por detrás de otros frameworks web de Rust. Necesitaba nightly y todavía no tenía soporte asíncrono.
      Ahora que superó el bache de la 0.5 quizá haya mejorado, pero el historial de desarrollo de Rocket hace que dé cierta duda usarlo en comparación con alternativas como Axum.
  • Sí hay uno: Poem[1].
    El autor menciona Flask, pero viendo la sección de “lo necesario”, cuesta decir que Flask también cumpla con esos requisitos. Aunque detesto bastante Django, para esos requerimientos creo que lo más cercano a lo que describe el autor es Django.
    En ese sentido, Poem tampoco es un buen candidato. En general, Poem se parece bastante a FastAPI, y eso es más bien un elogio. He usado cinco o seis frameworks web de Rust y la mayoría te hacen tocar bastante boilerplate en la configuración inicial. Si quieres obtener resultados rápido, eso es un problema, y en ese punto Poem encaja bien.
    actix tiene un rendimiento bastante bueno, pero si no estás apuntando a respuestas por debajo de 30 ms, de entrada hay pocas razones para mirar actix. Si necesitas algo como Pydantic, también hay crates que lo cubren hasta cierto punto: https://crates.io/crates/poem-openapi
    [1] https://github.com/poem-web/poem

    • No solo Django: también Rails, ASP .NET Core y muchos otros frameworks web completos con baterías incluidas entran en esa categoría.
      La clave es que sean un “framework”.
  • F# también vale la pena probarlo.
    Tiene casi todos los juegos de sistema de tipos que uno podría querer, además de las herramientas y comodidades necesarias. La gran desventaja sería que el manejo asíncrono y la administración de memoria no te consumen tanto tiempo como en Rust, así que existe el riesgo de terminar resolviendo de verdad las necesidades del negocio.
    Aun así, alguna parte de lidiar con Microsoft probablemente pueda llenar ese vacío.

    • ¿F# no necesita la máquina virtual de .NET? La mayoría de quienes eligen Rust que conozco valoran que siempre compile a código nativo, la previsibilidad y la ausencia de la aleatoriedad en los tiempos de recuperación del garbage collector.
    • Sigo dándole vueltas a si probar F#.
      ¿Cómo se compara con OCaml o Haskell?
  • Idea posiblemente impopular: Rust es un lenguaje de sistemas, y hacer trabajo web con Rust es desperdiciar esfuerzo.
    Para ese uso hay lenguajes y ecosistemas mucho mejores.

    • Contraargumento: desarrollar servicios web en Rust es tan fácil como hacerlo en Go o Java, y además obtienes un sistema de tipos excelente (¡tipos suma!), un gestor de paquetes excelente y muy buen rendimiento.
      Igual que en Java, en Rust puedes usar inyección de dependencias para compartir pools de conexiones, y las tareas en segundo plano basadas en threads también son muy simples de escribir.
      Google dijo en una presentación reciente que midió que los desarrolladores de Rust no son menos eficientes ni menos productivos que los de Go [1].
      Rust es un gran lenguaje, y no hay ninguna necesidad de limitarlo solo a la programación de sistemas. Puede hacer muchísimo más.
      [1] https://www.ardanlabs.com/news/2024/rust-at-google/
    • Yo siempre uso C/C++ para servidores web.
      Es liviano, permite llamar de forma fácil y rápida a C/C++ y a código de bajo nivel, y da mucho control sobre la parte de redes. Sin tener que aprender lenguajes dedicados a aplicaciones como PHP ni archivos de configuración de nginx/apache, puedes hacer casi cualquier cosa de una forma general e intuitiva.
      Me gustaría que hubiera una alternativa en Rust a algo como libmicrohttpd, y si existiera probablemente la usaría.
    • Estoy casi totalmente de acuerdo, pero quiero señalar que la intersección entre programación de sistemas y programación web no está vacía.
      Lo mismo pasa con la intersección entre programación embebida y programación web.
      Aun así, si opciones como Django, .Net o Go son viables, Rust en general probablemente sea una mala elección.
    • Es una inversión en eficiencia energética.
    • Tiene sentido en sistemas donde la memoria o la CPU están más restringidas de lo normal.
      Un framework web compilado estáticamente puede usar fácilmente entre 1/10 y 1/100 de la memoria/CPU que algo como Rails, Django o Flask.
  • Python tiene Django, C# tiene ASP .NET Core y Ruby tiene Rails.
    Si de verdad quieren hacer crecer mucho a Rust en desarrollo web, tienen que crear una solución completa.
    Rocket quizá sea lo más cercano, pero no trae tantas baterías incluidas como los frameworks mencionados arriba.

  • Lo que busca el autor es la versión Rust de ASP.NET Core, y no hay problema con eso.
    Hay gente a la que le gustan las opciones y armar las piezas, pero en muchos entornos es mucho más productivo que alguien ya haya curado las decisiones por ti.
    Reacciones como “¿y si quiero otro X? ¡Quizá Y sea un % mejor!” son comunes, pero pasan por alto que la integración en sí aporta muchísimo valor. Aunque cada biblioteca por separado pueda ser la mejor, si no encajan bien entre sí pueden convertirse en un basurero.
    Una de las razones por las que me gusta programar con ASP.NET 8 es que no tengo que preocuparme en absoluto por si el sistema de templates va a encajar bien con autenticación, inyección, routing, etc.

  • ¿No se mencionan loco-rs, poem ni rocket? Ya hay bastantes proyectos que apuntan a una experiencia con baterías incluidas.
    Lo que diferencia a estos proyectos de frameworks como leptos es que tienen una CLI que te guía. Eso también es lo que me gusta de Symfony, y ahí está la parte “perezosa” según yo.

  • Existe https://shuttle.rs
    No es solo un framework, sino también una herramienta que genera el boilerplate web alrededor, así que, según mi criterio, es una forma lo bastante floja de hacerlo

  • Este artículo aborda varios puntos distintos a la vez, así que idealmente habría que tratarlos por separado
    Si tienes pattern matching, no necesariamente necesitas un router. Basta con dividir la URL y hacer matching de variables estáticas/dinámicas según haga falta
    La autenticación, en cualquier lenguaje, normalmente se implementa uno mismo o se usa un SaaS como Firebase/Auth0, así que no es necesariamente un problema del lenguaje o del framework
    Las herramientas de CSS/JS no encajan bien con muchos frameworks frontend de Rust, como Dominator. Dominator está hecho en Rust, no en JS, y tiene su propio enfoque de estilos, por ejemplo adjuntar estilos a señales para que cambien en tiempo real
    Entiendo lo que dice el autor. De hecho, di varias vueltas intentando resolver muchos de los puntos del artículo, y también fue doloroso. Por ejemplo, https://github.com/dakom/dominator-workers-fluent-auth maneja muchas de las tareas mencionadas aquí sobre el framework de Cloudflare Workers, y además agrega otra cosa deseada: localización basada en Fluent
    Sería bueno tener un framework completo con baterías incluidas que haga todo, pero muchos proyectos reales van a querer cambiar esas decisiones prescriptivas y optar por implementarlo por su cuenta. Rust ya es lo bastante maduro incluso para la web frontend, y si sabes dónde mirar, puedes manejarlo todo con wasm-bindgen y demás

    • Decir que “si tienes pattern matching no necesitas un router” se queda corto
      Un framework web ofrece mucho más: redirecciones de URL, manejo de barras finales, gestión de URLs con distinción de mayúsculas y minúsculas, matching con regex complejas, etc.
      Decir que “la autenticación, en cualquier lenguaje, normalmente la implementas tú o usas un SaaS” es incorrecto. Django, Laravel, Rails y los lenguajes con baterías incluidas tienen una gestión de autenticación muy buena. Personalmente, creo que para el 90% de las organizaciones delegar la autenticación en un proveedor externo es un error enorme
      Que un desarrollador web experimentado pueda levantar en un día 10 CRUD básicos sin lidiar con complejidad innecesaria es una ventaja realmente enorme para los negocios pequeños
  • Si este artículo se hubiera centrado en C++ en lugar de Rust, ¿aplicaría en general lo mismo?
    Es un lenguaje de sistemas con una barrera de entrada alta, tiene tiempos de compilación, y esperar que un lenguaje que lleva menos de 10 años de uso extendido compita en accesibilidad con algo como Rails es demasiado pedir