eyecatch

今話題の Rust Loco 試してみた話

Posted on 2023/12/10
# Technology

Locoとは

Ruby on Rails のようなライブラリーを Rust で作ってるライブラリーで現在 5つあるうちの Stage3 まで開発が進んでいる。
小さいサービスや個人開発に適したライブラリーで認証認可やタスク、メーリングなど、1人でも多くのことができるようになることを目指して開発されている。

Rustの強力な静的型付けとパフォーマンスに Ruby on Rails 特有の開発のしやすさをふんだんに取り入れようとしていて、以前からRustとRuby on Rails は好きだったのですごく気になってるプロジェクトである。

今回まだ開発途中だったが、大きくアナウンスがあったので実際に触ってみて中身をみてみる。

Install手順

以下のコマンドで locoが提供している cli を cargo に入れる。

cargo install loco-cli

下記コマンドでプロジェクトを作成。
最初は3種類のテンプレートからプロジェクトが作成できた。

loco new
✔ ❯ App name? · myapp
✔ ❯ What would you like to build? · Saas app (with DB and user auth)

// App 3通りの選択肢がありました。
// 今回は Saas app を選択
- Saas app (with DB and user auth)
- Stateless service (minimal, no db)
- Stateless HTML (minimal, no db)

DBが必要だったので postgres を Docker で立ち上げる。

$ docker run -d -p 5432:5432 -e POSTGRES_USER=loco -e POSTGRES_DB=loco_app -e POSTGRES_PASSWORD="loco" postgres:15.3-alpine

下記コマンドでサーバーの立ち上げ。

cargo loco start

APIサーバーがPort 3000 で立ち上げ成功

                      ▄     ▀                     
                                 ▀  ▄             
                  ▄       ▀     ▄  ▄ ▄▀           
                                    ▄ ▀▄▄         
                        ▄     ▀    ▀  ▀▄▀█▄       
                                          ▀█▄     
▄▄▄▄▄▄▄  ▄▄▄▄▄▄▄▄▄   ▄▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄ ▀▀█    
 ██████  █████   ███ █████   ███ █████   ███ ▀█   
 ██████  █████   ███ █████   ▀▀▀ █████   ███ ▄█▄  
 ██████  █████   ███ █████       █████   ███ ████▄
 ██████  █████   ███ █████   ▄▄▄ █████   ███ █████
 ██████  █████   ███  ████   ███ █████   ███ ████▀
   ▀▀▀██▄ ▀▀▀▀▀▀▀▀▀▀  ▀▀▀▀▀▀▀▀▀▀  ▀▀▀▀▀▀▀▀▀▀ ██▀  
       ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀    
                https://loco.rs

environment: development
   database: automigrate
     logger: debug
      modes: server

listening on port 3000

Directory 構成

.
├── config // Environment毎の設定ファイル達
├── examples // デモが入る予定らしい
├── migration // sea-ormベースのマイグレーションに関するものたち
├── src
│   ├── bin
│   ├── controllers // routes と handlers が同じファイル内にある感じ
│   ├── fixtures // seed data が定義されている感じ?
│   ├── mailers // メールを送るための機構が詰まってる
│   ├── models // ActiveRecord みたいな感じ。 enntities model に 実体を impl していってる感じ。
│   │   └── _entities // seaORM が自動生成する model file. 
│   ├── tasks // Taskに関するフォルダ。
│   ├── views // Viewへ返すための LoginResponseのような Response が定義されてる。
│   └── workers // workers が含まれてる。現在は payment report を送る実装が demo で入ってる。
└── tests // Test fileたち
    ├── cmd
    ├── models
    │   └── snapshots
    ├── requests
    │   └── snapshots
    └── tasks

まだまだ開発途中ということもあってシンプルに構成されている。
Railsを意識してることが感じ取れる。
まだ service層や Handler が Route と一緒に定義されてたりしてるが、今後ストラクチャーは変更していくよう。

Modelsから DB にアクセス

例として実装されてる models > users の find_by_email をみてみる。

impl super::_entities::users::Model {
    /// finds a user by the provided email
    ///
    /// # Errors
    ///
    /// When could not find user by the given token or DB query error
    pub async fn find_by_email(db: &DatabaseConnection, email: &str) -> ModelResult<Self> {
        let user = users::Entity::find()
            .filter(users::Column::Email.eq(email))
            .one(db)
            .await?;
        user.ok_or_else(|| ModelError::EntityNotFound)
    }
    ...
}

seaORMが _entities::users を生成してるので、そこに実装を付け加えていくようなスタイル。
Ruby on Rails 特有の Fat Model になりそうな感じがするが、今後の実装をどうしていくか気になるところ。
Custom Errors は整理されてたのでエラーハンドリング周りは固まっているようだった。

#[derive(Debug, Validate, Deserialize)]
pub struct ModelValidator {
    #[validate(length(min = 2, message = "Name must be at least 2 characters long."))]
    pub name: String,
    #[validate(custom = "validation::is_valid_email")]
    pub email: String,
}

impl From<&ActiveModel> for ModelValidator {
    fn from(value: &ActiveModel) -> Self {
        Self {
            name: value.name.as_ref().to_string(),
            email: value.email.as_ref().to_string(),
        }
    }
}

他にも before_saveValidation なども実装されいる。Validationは Validator を使用しているので使ったことがある人は多いかもしれない。

一通り実装みての感想

構造などは別に Rails を触ったことない人でも簡単に理解はできそうではある。まだまだ開発途中なので 役割が1つのファイルに纏まってたりとしてるが、今後分けるつもりでいる意思が実装から読み取れる。
Ruby on RailsがOOPであるように、LocoもOOPに近いような、model に対してロジックをつけていくような思想になってるようなのでOOPが好きな人は気にいるかもしれない。
ただ Loco のコンセプトのThe one-person frameworkであるとおり 大きなプロジェクトを想定しているライブラリーではなさそうであるが、小-中規模のサービスや個人開発では大きく活躍できそうな感じはする。

気になるてんは Ruby on Rails とかで言われてた Fat Model などの意見が分かれるようなところは今後どうアプローチをとっていくかは気になるところ。

Ruby on Rails にあったコンソールで色々できる機能は是非とも欲しい。すごく欲しい。