- 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
newtmira 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
nframeworks 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
newtde 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
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
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
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
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
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/
É 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
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 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
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