3 pontos por GN⁺ 2024-10-07 | 1 comentários | Compartilhar no WhatsApp
  • Ao criar até mesmo pequenos apps web em Rust, falta uma experiência integrada como a do Django, o que aumenta o trabalho de juntar manualmente roteamento, login, banco de dados e recursos de administração
  • O framework necessário deveria trazer por padrão roteamento/handlers, templates, entrega de arquivos estáticos, login, permissões, interface com banco de dados, ferramentas de administração, WebSockets e hot reloading
  • Existem frameworks minimalistas como actix-web e axum, e frameworks SPA como Dioxus, Leptos e Yew, mas eles não montam por você a estrutura completa de um app web
  • Templates iniciais reduzem a configuração inicial, mas depois que o projeto se desvia deles, a mesclagem de mudanças e as atualizações de bibliotecas continuam sendo um fardo de manutenção
  • newt mira ser um toolkit web que combina componentes existentes de forma opinativa, com o objetivo de permitir iniciar pequenos apps web em minutos, não em dias

Falta um ponto de partida integrado para desenvolvimento web em Rust

  • Mesmo ao criar um pequeno projeto web em Rust, é necessário muito mais trabalho inicial de integração do que com Django ou frameworks semelhantes
  • A abordagem comum da comunidade Rust é mais próxima de juntar manualmente as peças necessárias
    • O Are We Web Yet? também orienta que, no desenvolvimento web em Rust, geralmente é preciso conectar as coisas manualmente e esperar configuração adicional no início
  • Esse trabalho extra não é apenas “um pouco mais”: na prática, há muitos itens a resolver antes mesmo de começar o projeto
  • Um framework web integrado tornaria mais fácil convencer pessoas a usar Rust em apps web
    • Entre as vantagens do Rust são mencionados o sistema de tipos, desempenho e as pausas para café durante a compilação

Componentes básicos necessários em quase todo app web

  • Roteamento/handlers

    • Requisições recebidas precisam ser enviadas ao handler adequado
    • Parâmetros de rota precisam ser tratados, e é ainda melhor quando há informação de tipos
    • Também seria bom ter tratamento de parâmetros de query e formulários
  • Templates

    • É preciso gerar HTML e, em alguns casos, também JSON ou XML
    • Lógica básica como condicionais, match/switch e loops é necessária
  • Entrega de arquivos estáticos

    • É preciso servir assets como CSS
    • Isso pode ser feito por um servidor separado, mas no desenvolvimento local e em implantações pequenas é conveniente incluir no mesmo servidor web
  • Login

    • Apps geralmente são multiusuário ou são implantados em redes públicas, então login quase sempre é necessário
    • Como é trabalhoso integrar isso toda vez, deveria ser fácil de usar desde o início
    • Customização e opt-out devem ser possíveis
  • Permissões

    • Em sistemas com vários usuários, os dados acessíveis ou os papéis variam
    • Só o padrão check(user, object, action) já permite ir bem longe
  • Interface com banco de dados

    • É preciso uma forma de armazenar os dados do app
    • Uma abordagem próxima de um ORM pode ser útil, mas uma abordagem mais leve também é possível
    • Como é usada para login, permissões e ferramentas de administração, torna-se um componente básico
  • Ferramentas de administração

    • Ao configurar uma aplicação em ambiente local ou em produção, é preciso fazer bootstrap de pelo menos um usuário ou de alguns dados
    • Algumas tarefas administrativas comuns deveriam vir embutidas para criar uma experiência fluida
  • WebSockets

    • Permitem criar funcionalidades que enviam dados aos usuários conectados de forma mais próxima do tempo real
  • Hot reloading

    • Mudanças no código ou nos templates devem ser refletidas o mais rápido possível, então isso é muito importante para a experiência do desenvolvedor

Recursos complementares necessários para projetos duradouros

  • Tarefas em segundo plano

    • Surgem funcionalidades que precisam ser executadas em determinados horários, e ter uma forma consistente facilita o desenvolvimento
  • Monitoramento/observabilidade

    • É necessário, a menos que o sistema seja o menor e de menor importância possível
    • Ajuda muito no momento em que passa a ser realmente indispensável
  • Cache

    • Há muitas formas de implementar, todas aumentam a complexidade, e se ficará mais rápido depende do contexto
    • Seria bom haver uma proposta no nível do framework, mas o usuário também pode lidar com isso diretamente
  • E-mail e notificações

    • Se há login, funcionalidade de e-mail pode ser praticamente necessária por causa da redefinição de senha
    • Outras notificações podem ser adicionadas quando forem necessárias, sem grande problema
  • Ferramentas de deploy

    • Seria bom ter uma forma consistente de fazer deploy para um local específico
    • Até mesmo um Dockerfile gerado automaticamente que possa ser usado no host escolhido já seria útil
  • Bundling de CSS/JS

    • Seria bom que a ferramenta web reconhecesse CSS e JS e os incluísse de forma natural
    • Não está claro se isso precisa necessariamente ser integrado

As lacunas deixadas pelo ecossistema web atual de Rust

  • Rust já tem muitas ferramentas de desenvolvimento web, mas nenhuma delas mira a experiência integrada desejada
  • Frameworks web minimalistas

    • actix-web e axum são mais próximos de pequenos frameworks como Flask e Sinatra
    • Eles oferecem uma boa experiência de desenvolvimento web aproveitando o sistema de tipos do Rust, mas praticamente não fornecem recursos além de handlers
    • Embora a maioria dos projetos possa ser criada com esses frameworks minimalistas, é trabalhoso ter que integrar manualmente os recursos necessários toda vez
  • Frameworks SPA

    • Dioxus, Leptos e Yew ocupam o espaço de usar Rust tanto no backend quanto no frontend, com WebAssembly para renderização no frontend
    • A experiência de criar o digital vigil com Yew foi agradável, mas não está claro se seria algo desejável em um ambiente real de produção
    • Esses frameworks também são excelentes para seus próprios objetivos, mas ainda exigem muito trabalho de integração
  • Conjuntos de bibliotecas individuais

    • Há muitas bibliotecas de templates, login, permissões e WebSocket
    • Alguns projetos e exemplos integram alguns componentes, mas é difícil encontrar algo que integre todas as peças usadas
    • Como o ecossistema se move rapidamente, alguns exemplos podem estar desatualizados
    • “Só conectar tudo” acaba sendo um trabalho de pesquisar e entender suficientemente bem como cada biblioteca funciona

A manutenção que templates iniciais não resolvem

  • O método existente geralmente consiste em escolher um framework base como actix-web ou axum, depois encontrar as peças necessárias, adicioná-las e conectá-las manualmente
  • Templates iniciais podem reduzir a dor inicial, mas o fardo de manutenção permanece
    • É preciso manter as bibliotecas atualizadas
    • Também é preciso lidar com breaking changes
    • Quando o projeto se afasta do template, fica difícil mesclar novamente mudanças do template
  • Ao operar vários projetos, em vez de atualizar um único framework, é preciso atualizar n frameworks personalizados individualmente
  • É melhor que um framework web que assuma o conjunto inteiro forneça orientações de upgrade entre versões
    • Breaking changes podem acontecer, mas podem ser documentadas
    • Isso pode reduzir situações em que surgem problemas por mudanças na interação entre dois componentes que não sabem que devem ser integrados um ao outro

O toolkit web que newt pretende ser

  • O framework web ideal para Rust deveria ter, junto com os recursos listados acima, boa documentação, changelog, versionamento cuidadoso, tratamento de breaking changes e uma comunidade
  • Atualmente essa ferramenta não existe, e não está claro se outra pessoa a está criando
  • A ferramenta em andamento é menos um framework e mais um toolkit web que conecta blocos de construção existentes de forma opinativa
  • O nome desse toolkit é nicole's web toolkit, ou newt de forma abreviada
    • Está publicado em um repositório público
    • Ainda não está em estado utilizável, e as mudanças mais recentes ainda não foram enviadas
    • Ainda não está pronto para receber contribuições
  • O objetivo do newt é permitir que, ao criar um novo pequeno app web, você comece a trabalhar no projeto real em minutos, em vez de passar dias fazendo integrações
  • Alguns componentes serão criados do zero conforme necessário
    • Isso pode ser mais fácil ou se encaixar de forma mais coesa
  • O ecossistema Rust precisa de um estado saudável com vários toolkits desse tipo, e há expectativa de que outras ferramentas também surjam

1 comentários

 
GN⁺ 2024-10-07
Opiniões no Hacker News
  • Fiquei surpreso que o Rocket (https://rocket.rs/) não esteja entre os frameworks listados pelo autor
    Não usei pessoalmente e prefiro axum/actix-web, que são menos prescritivos, mas, pelo que entendo, o objetivo do Rocket é muito mais próximo do framework com baterias incluídas que o autor quer, e ele já é um projeto bem antigo

    • O Rocket foi um dos primeiros frameworks Rust a apostar forte em uma boa experiência de desenvolvimento com macros procedurais, mas parece ter perdido bastante popularidade em várias partes da comunidade
      Por muito tempo, ele exigiu nightly Rust para compilar, e isso era um grande impeditivo para quem queria usar o framework em produção
      Além disso, ficou preso por cerca de 2 anos no estado de release candidate da versão 0.5.0, e a versão estável mais recente estava bem atrás de outros frameworks web em Rust. Exigia nightly e ainda não tinha suporte a async
      Agora que passou do obstáculo da 0.5, pode ter melhorado, mas o histórico de desenvolvimento do Rocket faz a gente hesitar em usá-lo quando comparado a alternativas como Axum
  • Existe um: Poem[1]
    O autor menciona Flask, mas, olhando a seção “o que é necessário”, é difícil dizer que o Flask também atenda a esses requisitos. Eu realmente não gosto de Django, mas, para esses requisitos, acho que o que mais se aproxima do que o autor descreve é o Django
    Nesse sentido, o Poem também não é um bom candidato. No geral, o Poem é bem parecido com o FastAPI, e isso é mais um elogio. Usei meia dúzia de frameworks web em Rust, e a maioria faz você mexer em bastante boilerplate na configuração inicial. Se você quer entregar resultado rapidamente, isso é um problema, e nesse ponto o Poem se encaixa bem
    O actix tem desempenho bastante bom, mas, se o objetivo não é ter respostas abaixo de 30 ms, há pouca razão para olhar para o actix logo de início. Se você precisa de algo como Pydantic, também há crates que fazem isso até certo ponto: https://crates.io/crates/poem-openapi
    [1] https://github.com/poem-web/poem

    • Não só Django, mas também Rails, ASP .NET Core e muitos outros frameworks web completos com baterias incluídas se encaixam nisso
      O ponto central é que é um “framework”
  • Vale experimentar F# também
    Ele tem praticamente todas as brincadeiras de sistema de tipos que você quer, além das ferramentas e conveniências necessárias. Um grande ponto negativo é que processamento assíncrono e gerenciamento de memória não consomem tanto tempo quanto em Rust, então há o risco de você acabar resolvendo de fato os requisitos de negócio
    Ainda assim, alguma parte do processo de lidar com a Microsoft talvez consiga preencher esse vazio

    • F# não precisa da máquina virtual .NET? A maioria dos que escolhem Rust que conheço gosta do fato de ele sempre compilar para código nativo, da previsibilidade e da ausência de aleatoriedade nos tempos de recuperação do garbage collector
    • Estou sempre pensando se devo experimentar F#
      Como ele se compara a OCaml ou Haskell?
  • Opinião talvez impopular: Rust é uma linguagem de sistemas, e fazer trabalho web em Rust é desperdício de esforço
    Há linguagens e ecossistemas muito melhores para esse uso

    • Contraponto: desenvolver serviços web em Rust é tão fácil quanto em Go ou Java, e, além disso, você ganha um excelente sistema de tipos (tipos soma!), um ótimo gerenciador de pacotes e desempenho muito bom
      Assim como em Java, em Rust também dá para usar injeção de dependência para compartilhar pools de conexões, e tarefas em background baseadas em threads também são muito simples de escrever
      O Google afirmou em uma apresentação recente que mediu que desenvolvedores Rust não são menos eficientes nem menos produtivos que desenvolvedores Go [1]
      Rust é uma excelente linguagem, e não há motivo algum para limitá-la apenas à programação de sistemas. Ela consegue fazer muito mais
      [1] https://www.ardanlabs.com/news/2024/rust-at-google/
    • Eu sempre uso C/C++ para servidores web
      É leve, permite chamar código C/C++ e de baixo nível de forma fácil e rápida, e também dá bastante controle sobre networking. Sem precisar aprender uma linguagem específica de aplicação como PHP ou arquivos de configuração do nginx/apache, dá para fazer quase tudo de uma forma genérica e intuitiva
      Seria bom existir uma alternativa em Rust a algo como libmicrohttpd, e acho que eu a usaria se existisse
    • Concordo quase totalmente, mas quero observar que a interseção entre programação de sistemas e programação web não é vazia
      O mesmo vale para a interseção entre programação embarcada e programação web
      Ainda assim, se opções como Django, .Net ou Go forem viáveis, Rust geralmente tende a ser uma má escolha
    • É um investimento em eficiência energética
    • Faz sentido em sistemas em que memória ou CPU são mais restritas que o normal
      Um framework web compilado estaticamente pode facilmente usar de 1/10 a 1/100 da memória/CPU de algo como Rails, Django ou Flask
  • Python tem Django, C# tem ASP .NET Core, Ruby tem Rails
    Se você realmente quer fazer Rust crescer muito no desenvolvimento web, precisa criar uma solução completa
    O Rocket talvez seja o mais próximo, mas não é tão “baterias incluídas” quanto os frameworks mencionados acima

  • O que o autor procura é a versão Rust do ASP.NET Core, e não há problema nisso
    Há quem goste de opções e montagem manual, mas, em muitos ambientes, ter escolhas já selecionadas para você é muito mais produtivo
    Reações como “e se eu quiser outro X? Y pode ser X% melhor!” são comuns, mas deixam passar o fato de que a integração em si tem um valor enorme. Bibliotecas individuais podem ser as melhores quando vistas separadamente, mas, se não se encaixarem de forma fluida, podem virar um monte de lixo
    O motivo de eu gostar de programar com ASP.NET 8 é que não preciso me preocupar em absoluto se o sistema de templates vai se encaixar bem com autenticação, injeção, roteamento etc.

  • Nenhuma menção a loco-rs, poem, rocket? Já existem vários projetos mirando uma experiência com baterias incluídas
    O que diferencia esses projetos de frameworks como leptos é que eles têm uma CLI que guia você. É isso que gosto no Symfony, e é aí que está a parte “preguiçosa”, na minha opinião

  • Existe o https://shuttle.rs
    Não é só um framework, mas também uma ferramenta que gera o boilerplate web ao redor, então, para mim, já é uma forma suficientemente preguiçosa

  • Este texto aborda vários pontos diferentes ao mesmo tempo, então o ideal seria tratar cada um separadamente
    Se há pattern matching, um roteador não é necessariamente indispensável. Basta dividir a URL e fazer o match de variáveis estáticas/dinâmicas conforme necessário
    Autenticação, em qualquer linguagem, normalmente é algo que você implementa por conta própria ou usa um SaaS como Firebase/Auth0, então não é necessariamente um problema da linguagem ou do framework
    Ferramentas de CSS/JS não se encaixam bem em muitos frameworks frontend em Rust, como o Dominator. O Dominator é feito em Rust, não em JS, e tem sua própria abordagem de estilização, como vincular estilos a sinais para que mudem em tempo real
    Entendo o que o autor quer dizer. De fato, já rodei várias vezes tentando resolver muitos dos itens do texto, e foi doloroso. Por exemplo, https://github.com/dakom/dominator-workers-fluent-auth lida com muitas das tarefas citadas aqui sobre um framework para Cloudflare Workers, e ainda acrescenta uma funcionalidade desejada extra: localização baseada em Fluent
    Seria bom ter um framework completo com baterias incluídas que fizesse tudo, mas muitos projetos reais vão querer mudar essas decisões prescritivas e seguir pelo caminho de implementar por conta própria. Rust já é maduro o suficiente também no frontend web e, se você souber onde procurar, dá para lidar com tudo usando wasm-bindgen e afins

    • Dizer que “com pattern matching, não é preciso um roteador” é insuficiente
      Um framework web oferece muito mais: redirecionamento de URLs, tratamento de barra final, gerenciamento de URLs com distinção entre maiúsculas e minúsculas, matching por regexes complexas etc.
      Dizer que “autenticação, em qualquer linguagem, normalmente é algo que você implementa por conta própria ou usa um SaaS” está errado. Django, Laravel, Rails e linguagens/frameworks com baterias incluídas têm uma gestão de autenticação muito boa. Pessoalmente, acho que para 90% das organizações terceirizar autenticação para um provedor externo é um erro enorme
      O fato de um desenvolvedor web experiente conseguir colocar no ar 10 CRUDs básicos em um dia, sem lidar com complexidade desnecessária, é uma vantagem realmente enorme para pequenos negócios
  • Se este texto tivesse focado em C++ em vez de Rust, em geral valeria dizer a mesma coisa?
    É uma linguagem de sistemas com alta barreira de entrada, também tem tempo de compilação, e é irrealista esperar que uma linguagem amplamente usada há menos de 10 anos compita em acessibilidade com algo como Rails