Loco 0.14 on Cathyos: 始め方

@nabbisen

はじめに

Loco は 2021 年頃に登場した比較的新しい Rust 製 Web フレームワークです。Ruby on Rails の影響を強く受けており、開発者が生産性を発揮できるように設計されています。ルーティング、ミドルウェア、リクエスト処理等、さまざまな機能が搭載されています。モダンで直感的な開発ができるように意識されています。

この記事で、数分でユーザー管理機能を持つ Web API の開発を始める方法をご紹介します。素晴らしいアプリテンプレートが支援してくれます。

環境

  • OS: Cathyos (Arch Linux ベース)
  • プログラミング言語: Rust 1.84.0
  • アプリ: Loco 0.14.0

チュートリアル

loco インストール

loco 実行ファイルをまず取得します。

$ cargo install loco

結果は以下の通りでした:

    Updating crates.io index
  Downloaded loco v0.14.0
  Downloaded 1 crate (367.8 KB) in 0.16s
  Installing loco v0.14.0
  (...)
   Compiling loco v0.14.0
    Finished `release` profile [optimized] target(s) in 16.72s
  Installing /home/nabbisen/.cargo/bin/loco
   Installed package `loco v0.14.0` (executable `loco`)

そしてこうなりました :)

$ loco --version
loco 0.14.0

cargo によってインストールされる実行ファイルの有効化

$PATH~/.cargo/bin が含まれていない場合、loco は見付からないというエラーになるでしょう。その時は、次の行を ~/.fish_profile に加えることが必要です:

set -U fish_user_paths $HOME/.cargo/bin $fish_user_paths

ORM 準備 (必要に応じて)

データべーが必要な場合、次の crate を追加でインストールします:

$ cargo install sea-orm-cli

私はインストールしました。

プロジェクト作成

準備環境です。さぁ始めましょう:

$ loco new

どんなアプリをつくるのかをたずねられます。私は以下のように進めました:

✔ ❯ App name? · loco-example
? ❯ What would you like to build? ›
  Saas App with server side rendering
  Saas App with client side rendering
❯ Rest API (with DB and user auth)
  lightweight-service (minimal, only controllers and views)
  Advanced
✔ ❯ Select a DB Provider · Sqlite
✔ ❯ Select your background worker type · Async (in-process tokio async tasks)

結果は以下の通りでした:

🚂 Loco app generated successfully in:
/(...)/loco-example

プロジェクト構成を理解する

やりました。プロジェクトが作成されました。中に入ってみましょう:

$ cd loco-example/

中のものを見てみましょう:

$ ls
drwxr-xr-x    - (user) 10  1月 12:46 .cargo
drwxr-xr-x    - (user) 10  1月 12:46 .github
drwxr-xr-x    - (user) 10  1月 12:46 config
drwxr-xr-x    - (user) 10  1月 12:46 examples
drwxr-xr-x    - (user) 10  1月 12:46 migration
drwxr-xr-x    - (user) 10  1月 12:46 src
drwxr-xr-x    - (user) 10  1月 12:46 tests
.rw-r--r--  339 (user) 10  1月 12:46 .gitignore
.rw-r--r--   49 (user) 10  1月 12:46 .rustfmt.toml
.rw-r--r-- 1.3k (user) 10  1月 12:46 Cargo.toml
.rw-r--r-- 2.4k (user) 10  1月 12:46 README.md

サーバー起動

$ cargo loco start

結果は以下の通りでした:

   Compiling loco-example v0.1.0 (/(...)/loco-example)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 41.10s
     Running `target/debug/loco_example-cli start`
2025-01-10T03:51:27.386666Z  WARN app: loco_rs::boot: pretty backtraces are enabled (this is great for development but has a runtime cost for production. disable with `logger.pretty_backtrace` in your config yaml) environment=development
2025-01-10T03:51:27.394779Z  INFO app: loco_rs::db: auto migrating environment=development
2025-01-10T03:51:27.398632Z  INFO app: sea_orm_migration::migrator: Applying all pending migrations environment=development
2025-01-10T03:51:27.399422Z  INFO app: sea_orm_migration::migrator: Applying migration 'm20220101_000001_users' environment=development
2025-01-10T03:51:27.399875Z  INFO app: sea_orm_migration::migrator: Migration 'm20220101_000001_users' has been applied environment=development
2025-01-10T03:51:27.400196Z  INFO app: loco_rs::boot: initializers loaded initializers="" environment=development
2025-01-10T03:51:27.412320Z  INFO app: loco_rs::controller::app_routes: [GET] /_ping environment=development
2025-01-10T03:51:27.412500Z  INFO app: loco_rs::controller::app_routes: [GET] /_health environment=development
2025-01-10T03:51:27.412558Z  INFO app: loco_rs::controller::app_routes: [POST] /api/auth/register environment=development
2025-01-10T03:51:27.412591Z  INFO app: loco_rs::controller::app_routes: [GET] /api/auth/verify/{token} environment=development
2025-01-10T03:51:27.412648Z  INFO app: loco_rs::controller::app_routes: [POST] /api/auth/login environment=development
2025-01-10T03:51:27.412693Z  INFO app: loco_rs::controller::app_routes: [POST] /api/auth/forgot environment=development
2025-01-10T03:51:27.412724Z  INFO app: loco_rs::controller::app_routes: [POST] /api/auth/reset environment=development
2025-01-10T03:51:27.412758Z  INFO app: loco_rs::controller::app_routes: [GET] /api/auth/current environment=development
2025-01-10T03:51:27.412796Z  INFO app: loco_rs::controller::app_routes: [POST] /api/auth/magic-link environment=development
2025-01-10T03:51:27.412827Z  INFO app: loco_rs::controller::app_routes: [GET] /api/auth/magic-link/{token} environment=development
2025-01-10T03:51:27.412957Z  INFO app: loco_rs::controller::app_routes: +middleware name="limit_payload" environment=development
2025-01-10T03:51:27.413002Z  INFO app: loco_rs::controller::app_routes: +middleware name="catch_panic" environment=development
2025-01-10T03:51:27.413040Z  INFO app: loco_rs::controller::app_routes: +middleware name="etag" environment=development
2025-01-10T03:51:27.413106Z  INFO app: loco_rs::controller::app_routes: +middleware name="logger" environment=development
2025-01-10T03:51:27.413144Z  INFO app: loco_rs::controller::app_routes: +middleware name="request_id" environment=development
2025-01-10T03:51:27.413184Z  INFO app: loco_rs::controller::app_routes: +middleware name="fallback" environment=development
2025-01-10T03:51:27.413239Z  INFO app: loco_rs::controller::app_routes: +middleware name="powered_by" environment=development

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

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

listening on http://localhost:5150

サーバーが起動しました !!

なおルーティングは src/controllers/auth.rs に定義されています:

pub fn routes() -> Routes {
    Routes::new()
        .prefix("/api/auth")
        .add("/register", post(register))
        .add("/verify/{token}", get(verify))
        .add("/login", post(login))
        .add("/forgot", post(forgot))
        .add("/reset", post(reset))
        .add("/current", get(current))
        .add("/magic-link", post(magic_link))
        .add("/magic-link/{token}", get(magic_link_verify))
}

ブラウザからアクセス (おまけ)

http://localhost:5150 が以下のように表示されます:

access via browser

curl でユーザー登録

ローカルにメールサービスが存在しない場合、事前に config/development.yaml を更新して smtp を無効化しておきます:

  mailer:
    # SMTP mailer configuration.
    smtp:
      # Enable/Disable smtp mailer.
-       enable: true
+       enable: false

この時、サーバーの再起動が必要です。

curl でアクセスして、ユーザーを登録します:

$ curl -X POST http://localhost:5150/api/auth/register -H "content-type: application/json" --data '{"email":"[email protected]", "password":"testpassword", "name":"testname"}'

SQLite のデータベース・ファイルがルート・ディレクトリに作成されます。loco-example_development.sqlite というファイル名でした。 データベースを開いてみましょう:

$ sqlite3 loco-example_development.sqlite

データを確かめてみましょう:

sqlite> .tables
seaql_migrations  users           

sqlite> select * from users;
2025-01-10 04:08:06|2025-01-10 04:08:06|(...)|test@test.test|$argon2id$v=19$m=19456,t=2,p=(...)|(...)|testname|||(...)|2025-01-10T13:08:06.638250752+09:00|||

sqlite> .schema users
CREATE TABLE IF NOT EXISTS "users" ( "created_at" timestamp_with_timezone_text NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" timestamp_with_timezone_text NOT NULL DEFAULT CURRENT_TIMESTAMP, "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "pid" uuid_text NOT NULL, "email" varchar NOT NULL UNIQUE, "password" varchar NOT NULL, "api_key" varchar NOT NULL UNIQUE, "name" varchar NOT NULL, "reset_token" varchar NULL, "reset_sent_at" timestamp_with_timezone_text NULL, "email_verification_token" varchar NULL, "email_verification_sent_at" timestamp_with_timezone_text NULL, "email_verified_at" timestamp_with_timezone_text NULL, "magic_link_token" varchar NULL, "magic_link_expiration" timestamp_with_timezone_text NULL );

おわりに

ここまでで cargo から Loco をインストールして、ユーザー登録用 Web API を作成する流れを見て来ました。この他の API、すなわちログインやアカウントのリセットなども提供されています。

あなたがこのすばらしいフレームワークに習熟するのに、この記事が何かしらのお役に立てたら幸いです !!!

参考文献


Comments or feedbacks are welcomed and appreciated.