- Rwf adalah framework komprehensif untuk membuat aplikasi web dengan Rust, dan menyediakan fitur bawaan yang diperlukan untuk membangun aplikasi web yang cepat dan aman berdasarkan pola MVC klasik
- Fitur dasarnya mencakup server HTTP, ORM untuk kueri PostgreSQL, template dinamis, autentikasi dan sesi pengguna, middleware, background jobs dan scheduled jobs, serta migrasi database
- Juga menyediakan framework REST bawaan dengan dukungan serialisasi JSON, WebSockets, hosting file statis, konfigurasi per lingkungan, logging dan metrics, serta CLI
- Terintegrasi erat dengan Hotwired Turbo untuk membuat SPA yang digerakkan backend, serta menyediakan server WSGI untuk migrasi Django/Flask dan server Rack untuk migrasi Rails
- Saat ini berstatus beta dan sedang mencari early adopter; sebagian besar fiturnya disebut sudah dalam kondisi baik dan dokumentasinya sudah cukup layak digunakan
Framework web MVC untuk Rust
- Rwf adalah framework komprehensif untuk membangun aplikasi web dengan Rust
- Ditulis dengan pola MVC(model-view-controller) klasik
- Bertujuan untuk menyertakan secara bawaan fitur-fitur yang diperlukan agar pembuatan aplikasi web yang cepat dan aman menjadi mudah
- Dokumentasi tersedia di dokumentasi resmi
Fitur yang disediakan
- Server dan pemrosesan request
- Data dan struktur aplikasi
- Menyediakan ORM yang ramah pengguna untuk memudahkan pembuatan kueri PostgreSQL
- Mendukung migrasi database
- Menyediakan Dynamic templates
- Termasuk Authentication dan sesi pengguna bawaan
- API dan pemrosesan pekerjaan
- Operasional dan alat pengembangan
- Mendukung konfigurasi per lingkungan
- Menyediakan logging dan metrics
- Termasuk CLI
Dukungan Hotwired Turbo dan migrasi
Mulai cepat
- Buat aplikasi biner Rust lalu tambahkan
rwf sebagai dependensi
cargo add rwf
- Aplikasi dasar mendefinisikan controller dan route menggunakan
rwf::prelude::* dan rwf::http::Server
use rwf::prelude::*;
use rwf::http::Server;
#[controller]
async fn index() -> Response {
Response::new().html("Welcome to Rwf!\n\n")
}
#[tokio::main]
async fn main() {
Server::new(vec![
route!("/" => index),
])
.launch()
.await
.unwrap();
}
Contoh dan status proyek
- Kasus penggunaan umum dapat dilihat di examples
- Rwf saat ini berstatus beta dan sedang mencari early adopter
- Sebagian besar fitur disebut sudah dalam kondisi baik dan dokumentasinya sudah cukup layak digunakan
- Kontribusi disambut; panduan ada di CONTRIBUTING, panduan struktur kode di ARCHITECTURE, dan daftar fitur yang diinginkan di ROADMAP
1 komentar
Opini Hacker News
Rilisnya terasa cukup tidak realistis, dan selamat. Pelajaran terbesar yang saya dapat setelah lama mengerjakan web MVC dengan Rails adalah bahwa framework harus sangat menahan logika bisnis di lapisan model
Menurut saya sebaiknya jangan memasukkan callback yang disebut Active Record ke dalam model data, misalnya hook seperti
afterCreate. Memang belum ada di ORM-nya, tetapi kalau ada di roadmap, saya rasa lebih baik tetap tidak adaNamun ini hanya benar-benar berjalan baik jika layanan, yaitu lapisan logika bisnis, sangat dianjurkan. Sebagian besar aplikasi Rails saya menyusun objek command/service dengan gem seperti Interactor
Menurut saya MVC saja, dan karena itu konfigurasi bawaan Rails saja, tidak ideal untuk menulis aplikasi yang bisa dioperasikan karena tidak adanya lapisan service. Saya juga penasaran mengapa tidak memanfaatkan ORM atau query builder yang sudah ada di komunitas. Saya sendiri belum pernah menulis Rust satu baris pun, tetapi makin lama makin penasaran
Service menurut saya hampir semuanya harus berupa potongan kode spesifik yang lebih kompleks yang dipicu dari model. Controller tipis, model tebal adalah yang terbaik dari sisi debugging, kerapian, dan kemudahan ditemukan; ketika banyak memakai service, berdasarkan pengalaman, banyak kode spaghetti yang muncul
Dari sudut pandang berorientasi objek murni pun, model adalah objek dasar yang mendefinisikan entitas.
Userharus mengetahui semua yang perlu ia ketahui tentang dirinya sendiri, dan berkomunikasi dengan entitas lain lewat pesanNamun saya setuju soal callback. Callback menciptakan banyak efek samping aneh dan membuat debugging benar-benar sulit
Itu bisa saja dilakukan, tetapi menjadi cukup sulit untuk menalar bagaimana suatu entitas dapat diperbarui. Karena prosedur dalam jumlah berapa pun bisa memperbaruinya dan masing-masing bisa memiliki aturan bisnis sendiri. Kalau begitu, prosedur bisa langsung menulis ke database dan modelnya dihapus saja
Namun setelah lebih dari 20 tahun mengembangkan perangkat lunak, saya sampai pada kesimpulan bahwa enkapsulasi adalah beban, bukan fitur, dan data harus dipisahkan dari operasi yang dilakukan terhadap data itu. Ini disebut data-oriented design atau data-oriented programming, dan saya bukan satu-satunya yang sampai pada kesimpulan yang sama
Ada cara pemodelan lain yang bisa diskalakan dengan baik, dan ada beberapa tulisan terkait. Ada tulisan dari orang Basecamp: https://dev.37signals.com/vanilla-rails-is-plenty/
Tentu saja ini sangat berorientasi objek, jadi saya sendiri juga tidak terlalu menyukainya. Misalnya framework Phoenix di Elixir memakai context untuk mengelompokkan fungsionalitas terkait, yang secara sederhana bisa dilihat sebagai facade
Jika Anda suka service, silakan dipakai, tetapi menurut saya mengatakan MVC tidak cukup untuk tingkat produksi agak meleset. Menangani proses bisnis yang berat dengan callback model memang tidak baik, tetapi untuk pekerjaan kecil yang merapikan data ke bentuk yang benar, itu cukup oke
Mungkin saya bias, terutama karena pengalaman pemrograman saya dimulai dari PHP untuk Wordpress yang banyak sekali memakai hook
Yang saya buat memiliki spesifikasi tabel yang bisa diterjemahkan menjadi definisi SQL atau menghasilkan form HTML yang diformat rapi. Controller terpisah menangani semua koneksi DB dan operasi CRUD, dan ada hook sebelum/sesudah yang bisa dengan mudah melakukan referensi silang ke tabel dan constraint lain bila diperlukan
Ini berjalan cukup baik, tetapi kalau bisa, saya akan segera pindah ke Laravel
Kalau ini framework REST, saya berharap secara bawaan bisa menghasilkan definisi Swagger/OpenAPI. Menurut saya itu salah satu killer feature FastAPI
Saya juga kurang paham mengapa membuat ORM sendiri alih-alih berintegrasi dengan ORM yang sudah ada seperti diesel.rs, dan mengapa membuat bahasa template sendiri alih-alih memilih engine template populer yang sudah ada
Selain itu, proyeknya terlihat sangat menarik dan saya akan terus memantaunya
[0] https://diesel.rs/
[1] https://crates.io/categories/template-engine
Secara umum itu adalah upaya awal yang bagus untuk memetakan tipe database ke tipe Rust, tetapi ORM harus lebih fleksibel dan lebih nyaman dipakai. Karena query semestinya dibuat lebih mudah, bukan lebih sulit :)
Untuk template, membuat bahasa sendiri itu hampir seperti ritual masuk klub nerd usia 30-an ke atas. Saya belum membaca Dragon Book, tetapi waktu sekolah saya sangat ingin mengambil mata kuliah itu. Untuk hal yang sama pun selalu ada banyak implementasi, dan rasanya tepat memakai implementasi ini yang sangat dekat meniru apa yang dilakukan ERB di Rails
Dari sudut pandang SRE, saya tertarik pada https://levkk.github.io/rwf/migrating-from-python/. Di satu sisi, keren sekali mereka berhasil melakukannya, tetapi dari perspektif SRE yang melihat stabilitas, ini membuat saya menjerit dalam hati
Saat skalanya membesar, ini seharusnya ditangani oleh reverse proxy seperti Caddy, Nginx, atau Traefik
Menulis server WSGI yang stabil itu mungkin, dan tidak terlalu sulit jika sedikit memperhatikan detail seperti jumlah thread, vacuum, atau restart setiap n request seperti php-fpm dulu. Pada dasarnya, jika Anda mengimplementasikan sebagian besar opsi yang dimiliki uwsgi, berarti Anda sudah berada di jalur yang benar. Menjadikan Rwf dapat dibandingkan dengan menjalankan Gunicorn ada di roadmap
Pemilihan namanya benar-benar luar biasa. Memang itu salah satu cara untuk muncul di urutan teratas hasil pencarian :P
Serius, ini dibuat dengan baik. Membuat framework yang bagus adalah pekerjaan yang mengejutkan besarnya, dan selalu menyenangkan melihat orang mengeksplorasi ruang desain serta mencoba ide baru
rwfRustOnWeb.com juga bisa dibeli seharga $10 :) cuma asal ngomong
Saya suka ungkapan “pikirkan Rails, bukan Flask”. Bahasa dengan tipe statis juga perlu lebih banyak, atau lebih baik, framework yang opinionated seperti Rails/Django
Dibuat dengan baik. Layak dicoba agar bisa diperkenalkan di https://www.arewewebyet.org/
Bagus! Django/Rails yang dibuat dengan bahasa kelas atas
Sebagai saran,
async-traitmungkin sudah stabil sekarang sehingga makro mungkin tidak lagi diperlukan, dan akan bagus jika menambahkan integrasi OpenTelemetry agar metrik dan tracing bisa didapat secara default. Untuk target Linux, jemalloc juga bagus digunakanSaya berencana menambahkan tag OpenTelemetry ke fungsi-fungsi di crate
tracing. jemalloc bisa ditambahkan ke aplikasi biner yang menggunakan Rwf, dan tidak perlu dimasukkan sebagai dependency library[1] https://blog.rust-lang.org/2023/12/21/async-fn-rpit-in-trait...
Saya sempat mencoba belajar Rust, tetapi menyerah di awal. Datang dari C#, C/C++, Java, dan Python, Rust terasa aneh
Yang membuat saya menyerah bukan keanehannya itu sendiri, melainkan fakta bahwa kecepatan menyelesaikan satu pekerjaan lebih lambat dibanding bahasa seperti C#, Java, dan Python
Belakangan saya terutama mengerjakan pengembangan web, jadi kemudahan penggunaan dan produktivitas adalah prioritas utama. Rust mungkin sedikit lebih baik dalam throughput dan kecepatan, tetapi jika melihat benchmark framework web modern, C# dan Java juga cukup bagus dalam hal ini
Saya harap ini tidak dibaca sebagai kritik terhadap Rust atau sebagai upaya mengecilkan pencapaian besar membuat framework MVC dari nol. Ini lebih dekat ke soal “alat yang tepat untuk pekerjaan yang tepat”
Untuk melewati kurva belajar, perlu motivasi yang kuat. Entah karena harus memakai bahasa itu, tertarik pada manfaat type system dan safety, atau punya alasan konkret sendiri
Kalau motivasi itu tidak ada, sama sekali tidak masalah. Saya juga tidak memilikinya di awal, sehingga upaya belajar pertama saya tidak berjalan jauh. Seperti yang dirasakan banyak orang, Rust membutuhkan waktu lebih lama daripada Java atau Python untuk menyelesaikan pekerjaan, dan menuntut lebih banyak pemikiran di depan. Dalam situasi tertentu itu bernilai, tetapi jika tidak jelas mengapa Anda harus menerima trade-off itu, tidak ada alasan kuat untuk terus lanjut
Belakangan ini saya meninggalkan loader JS webpack dan memakai loader Rust yang 50 kali lebih cepat, dan saya juga jadi tertarik pada Rust. Rust memberi peningkatan performa yang besar, dan sekarang C++ dan Rust adalah bahasa favorit saya
Saya sudah mengevaluasi semua kandidat yang umum disebut untuk pekerjaan backend Rust dan membuat prototipe kecil. Sejauh ini, meski masih lebih low-level daripada yang saya inginkan, saya dengan enggan sepakat dengan kesimpulan kolektif bahwa secara keseluruhan Axum adalah pilihan terbaik
Kandidat lainnya adalah Loco dan Rocket. Loco terlalu mirip Rails, dan pada Rocket, setelah lebih banyak memakai Rust, makronya mulai terasa mengganggu
Framework ini tampaknya sangat cocok dengan kriteria saya: “batteries included tetapi tidak terlalu preskriptif”. Tambahan yang bagus untuk ekosistem