3 poin oleh GN⁺ 2024-10-23 | 1 komentar | Bagikan ke WhatsApp
  • 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

 
GN⁺ 2024-10-23
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 ada
    Namun 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

    • Saya penasaran dari mana sudut pandang ini berasal. Menurut saya justru sebaliknya: sebanyak mungkin logika bisnis harus ada di model
      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. User harus mengetahui semua yang perlu ia ketahui tentang dirinya sendiri, dan berkomunikasi dengan entitas lain lewat pesan
      Namun saya setuju soal callback. Callback menciptakan banyak efek samping aneh dan membuat debugging benar-benar sulit
    • Kalau tidak ada logika bisnis, saya tidak tahu sebenarnya model itu apa. Kedengarannya seperti Anda menginginkan susunan yang menyebut struct sebagai model dan prosedur sebagai service
      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
    • Saya setuju bahwa logika bisnis tidak semestinya ada di model. Martin Fowler dan Robert C. Martin menyebut hal seperti ini anemic domain model, dan itu berlawanan dengan pendekatan pengembangan enterprise lama yang berat pada object-oriented dan pattern
      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
    • Pernyataan bahwa MVC saja kurang untuk aplikasi tingkat produksi itu klaim yang cukup besar. Secara pribadi saya tidak suka service object, karena tersebar di mana-mana dan merusak discoverability
      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
    • Menarik. Di perusahaan, kami membuat ORM PHP sendiri, karena penggunaan library open-source seperti Laravel dilarang, dan saya merasa hook sangat berguna
      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

    • Saya pernah mencoba Diesel beberapa tahun lalu, dan bagi saya rasanya terlalu Rust-ish. Skema harus didefinisikan dua kali, dan karena tidak bisa memakai struct yang sama untuk insert dan query, pada dasarnya harus didefinisikan tiga kali
      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
    • https://github.com/poem-web/poem adalah framework Rust yang menyediakan definisi Swagger secara bawaan
    • Saya penasaran apakah ada yang tahu framework serupa yang bekerja sebaliknya. Maksudnya, definisi OpenAPI dipertahankan sebagai sumber kebenaran, lalu server memvalidasi apakah ia mengikutinya
    • Menurut saya menghasilkan OpenAPI dari server itu 100% killer feature. Kami memakainya dengan baik lewat Dropshot
    • Saya juga berharap framework REST akan menghasilkan definisi Swagger/OpenAPI secara bawaan. Namun sejauh yang saya pahami, ini bukan framework untuk membangun web API, melainkan framework MVC yang mengembalikan HTML
  • 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

    • Saya juga berpikir begitu, tetapi dengan cara ini engineer aplikasi bisa menguji perubahan secara lokal tanpa bolak-balik. Pada akhirnya ini kembali ke perdebatan lama monolith vs microservices
      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
    • Saya rasa penulis berasumsi bahwa jika pembacanya teknis, kebutuhan akan reverse proxy di depan server WSGI tidak perlu dijelaskan lagi
  • 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

    • Proyek-proyek Rust cenderung memilih nama yang luas, umum, dan agak pamer diri seperti ini, dan jujur saya pikir itu kesalahan besar. Crates.io akan menjadi kuburan proyek-proyek terbengkalai yang sudah mengamankan nama-nama yang terdengar bagus
    • “Row” juga nama yang bagus, dan sepertinya lebih mudah diucapkan daripada rwf
      RustOnWeb.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/

    • Cukup mengejutkan bahwa halaman ini tidak mencantumkan loco.rs. Padahal tampaknya itu yang paling mirip “Rails” di antara framework Rust
  • Bagus! Django/Rails yang dibuat dengan bahasa kelas atas
    Sebagai saran, async-trait mungkin 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 digunakan

    • Terima kasih. Saya sudah mencoba trait async standar, tetapi itu tidak mendukung dynamic dispatch yang banyak digunakan Rwf
      Saya 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 penasaran mengapa perlu memakai jemalloc untuk target Linux. Atau mengapa target lain tidak membutuhkannya
  • 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”

    • Saya sepenuhnya mengerti maksudnya. Banyak orang, termasuk saya, punya pengalaman serupa di awal
      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

    • Oh, bisa berbagi apa yang akhirnya Anda pakai setelah meninggalkan webpack?
  • 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

    • Bagaimana dengan Actix? Seingat saya dulu ada diskusi di HN tentang Actix dan Axum