このサイトは、只今WEB業界で活躍中のデザイナー、プログラマーの方々の情報を集めたweb統合情報サイトです。

Archives Details

Rust – Actix Web × MongoDB環境をサクッと起動

Rust

2024.01.18

この記事は最終更新日から1年以上が経過しています。

どもです。

昨年より業務でガッツリRustでの開発を行ってはいるのですが、主にクライアントアプリ開発の方で、そういえばサーバー周りはどうなっているのだろうと、最近はもごもご漁っている状況だったりします。

Rustのasync対応も終わり、サーバーフレームワークの方も安定且つ、増えて来ている状況で、全然Rustでのサーバー開発はアリだなと感じている今日このごろです。

というか、サーバー開発で使わない理由の少なさもあって、むしろ積極的にサーバー開発にRust採用していくべきだと思いますし、今後も増えていくのだろうと肌感で感じました。

という訳で、今日は、RustのサーバーフレームワークのActix Webを用いて、DBはmongodbでローカル開発環境をサクッと起ち上げて行きたいと思います。

 

HomebrewでMongoDBをインストール

HomebrewでMongoDBをインストールしていきます。この辺解説は割愛させていただきます。

brew tap mongodb/brew
brew install mongodb-community

バーションの確認

mongod --version

起動・停止方法の確認

brew services start mongodb-community
brew services stop mongodb-community

 

MongoDB compassでDB作成

MongoDBのGUIツールのMongoDB compassをインストールしましょう。

こちらは任意でインストールしていただければと。cliで行う方は飛ばして頂いて問題ありません。

MongoDB compass公式のHPよりcompassをインストールしていきます。

ダウンロードページは以下になります。該当するPlatformを選択しダウンロードしましょう。

ダウンロードページ

brewコマンドでmongodbを起動しましたら、MongoDB compass「mongodb://localhost:27017」で接続。+アイコンでデータベース「myApp」を作成、左上の「+ Create collection」ボタンを押下、Collection Name「users」で、「Create collection」ボタンを押下。

これで、DB名「myApp」、collectionは「users」の形で、準備が完了。

 

Actix Web

それでは、Actix Webとmongodbを用いて、APIを作っていきます。

まずは、cargo newで新規プロジェクト作成。

cargo new mongodb --bin

createは以下の3つを使用します。

[dependencies]
mongodb = "2"
actix-web = "^4"
serde = { version = "^1", features = ["derive"] }

プログラムを書いて行くのですが、Actix Webはサンプルが豊富で、mongodbを用いたサンプルも以下に存在します。なので、ソースだけ知りたい方は、こちらを見ていただければと。

GitHub

actix/examples

examplesのソースを追っていきましょう。まずは「src/model.rs」ですが、struct Userを定義しております。

User Model: src/model.rs

pub struct User {
    pub first_name: String,
    pub last_name: String,
    pub username: String,
    pub email: String,
}

 

はい。後は「main.rs」となります。createのインポートや、定数を定義しましょう。

先程のDB名、collection名もこちらで定義しております。

src/main.rs

mod model;

use actix_web::{get, post, web, App, HttpResponse, HttpServer};
use model::User;
use mongodb::{bson::doc, options::IndexOptions, Client, Collection, IndexModel};

const DB_NAME: &str = "myApp";
const COLL_NAME: &str = "users";

 

Actix Webでは、#[post(“/add_user”)]といったアトリビュートでのAPIの定義を行うことが可能です。以下の場合は /add_userのURIに対して、add_user関数を実行し、ユーザーを作成する処理(API)となります。

mongodbである、clientを引数collectionにアクセスし、ユーザーを作成。失敗したらエラーとなります。

ユーザー作成 POST: /add_user

/// Adds a new user to the "users" collection in the database.
#[post("/add_user")]
async fn add_user(client: web::Data<Client>, form: web::Form<User>) -> HttpResponse {
    let collection = client.database(DB_NAME).collection(COLL_NAME);
    let result = collection.insert_one(form.into_inner(), None).await;
    match result {
        Ok(_) => HttpResponse::Ok().body("user added"),
        Err(err) => HttpResponse::InternalServerError().body(err.to_string()),
    }
}

こちらは、ユーザーを参照するAPIとなります。usernameをURIに含め、DBを探索し該当するユーザーを取得します。

usernameに関してはuniqueとして設定されていますので、重複は想定していなくfind_oneで取得しています。

ユーザー参照 GET: /get_user/{username}

/// Gets the user with the supplied username.
#[get("/get_user/{username}")]
async fn get_user(client: web::Data<Client>, username: web::Path<String>) -> HttpResponse {
    let username = username.into_inner();
    let collection: Collection<User> = client.database(DB_NAME).collection(COLL_NAME);
    match collection
        .find_one(doc! { "username": &username }, None)
        .await
    {
        Ok(Some(user)) => HttpResponse::Ok().json(user),
        Ok(None) => {
            HttpResponse::NotFound().body(format!("No user found with username {username}"))
        }
        Err(err) => HttpResponse::InternalServerError().body(err.to_string()),
    }
}

サーバー起動時にcreate_username_index関数を呼び、ソースコードからDocumentsのusernameに対してindex設定を行っています。

なので、mongodb側でindexを外しユニークでは無くなっていたりすると、エラーとなります。

index処理

create_username_index(&client).await;

/// Creates an index on the "username" field to force the values to be unique.
async fn create_username_index(client: &Client) {
    let options = IndexOptions::builder().unique(true).build();
    let model = IndexModel::builder()
        .keys(doc! { "username": 1 })
        .options(options)
        .build();
    client
        .database(DB_NAME)
        .collection::<User>(COLL_NAME)
        .create_index(model, None)
        .await
        .expect("creating an index should succeed");
}

mainの処理は、mongodbにアクセスと、HttpServer::newでサーバーを起ち上げ、App::new()でmongodbのデータをapp data化。先程のAPIをservice化を行っています。

以下の環境で起動。

サーバー

http://127.0.0.1:8080

MongoDB

mongodb://localhost:27017

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    let uri = std::env::var("MONGODB_URI").unwrap_or_else(|_| "mongodb://localhost:27017".into());

    let client = Client::with_uri_str(uri).await.expect("failed to connect");
    create_username_index(&client).await;

    HttpServer::new(move || {
        App::new()
            .app_data(web::Data::new(client.clone()))
            .service(add_user)
            .service(get_user)
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

それでは、cargo runで起動しましょう。

cargo run

API疎通テスト

Postmanを用いてAPI疎通テストを行います。まずは、ユーザー作成したいので、POSTに設定で

URIは「http://127.0.0.1:8080/add_user」入力。

BodyはJSON形式で以下のデータを送信。

ユーザー作成 POST: /add_user

{
    "first_name": "daisuke",
    "last_name": "takayama",
    "username": "takayama_daisuke",
    "email": "webcyou@webcyou.com",
}

エラーが出なければ成功。では、作成したユーザーを取得しましょう。

ユーザー取得はGETで、URIを取得したいユーザー名も含めた「http://127.0.0.1:8080/get_user/takayama_daisuke」を入力。

ユーザー参照 GET: /get_user/{username}

レスポンスに該当するユーザーがJSON形式で返却されれば成功。

{
    "first_name": "daisuke",
    "last_name": "takayama",
    "username": "takayama_daisuke",
    "email": "webcyou@webcyou.com"
}

と、一旦ここまでで起動は成功。

いやぁ。爆速のサーバーが容易に扱える事に喜びを感じております。

引き続きRustのサーバー周りも追っていこうと思います。

ではではぁ。

Comment

Related Article

ゲーム開発に必要な基本数学入門

2025.08.15

Godot 4 & Rust 始め方

2025.06.19

Rustでつくる ふっかつのじゅもん

2025.04.29

Tauri(Rust) × AI で作る GitGUIクライアントアプリ その5

2025.04.14

Tauri(Rust) × AI で作る GitGUIクライアントアプリ その4

2025.04.10

Tauri(Rust) × AI で作る GitGUIクライアントアプリ その3

2025.04.08

Tauri(Rust) × AI で作る GitGUIクライアントアプリ その2

2025.04.07

Tauri(Rust) × AI で作る GitGUIクライアントアプリ その1

2025.04.05

keyring-rsで、Macのキーチェーンに登録する。

2025.04.04

RustとWebAssemblyによるゲーム開発 Webpack5対応

2025.03.27

CATEGORY LIST

LATEST NEWS

【2026】【VMware Fusion】MacでWindowsを無料で扱う。

windows

2026.07.19

Raspberry Pi 5 でマインクラフトサーバーを立てる(Java版 × 統合版クロスプレイ対応)

RaspberryPi

2026.06.24

ラズパイが高い。

RaspberryPi

2026.05.26

【Claude Code】フル稼働。ToDo Appを様々なGUIフレームワーク用いて作らせる。

AI・Bot・algorithm

2026.05.24

Macで歩く「たのしいバイナリの歩き方」うさみみハリケーンの代わりに、Cheat Engine / Bit slicerを使用する

アセンブラ

2026.04.12

Macで歩く「たのしいバイナリの歩き方」

アセンブラ

2026.04.10

【Railway】ひたすら安く個人開発サービスを運用する計画

サーバー

2026.04.06

たびのきろく

イベント

2026.02.23

【Railway】MySQLサービスをコスト抑えて運用する

運用

2026.01.19

あけましておめでとうございますmm DjangoアプリをRailwayに移行する。

運用

2026.01.06

効率の良い AI駆動開発について考える

AI・Bot・algorithm

2025.11.09

MacとClaude Codeで構築する cc65(NES)開発環境

Game

2025.10.24

RANKING

Follow

SPONSOR

現在、掲載募集中です。



Links

About Us

WEBデザイナーの、WEBデザイナーによる、WEBデザイナーの為のサイト。「みんなで書こう!」と仲間を募ってみたが、結局書くのは自分だけとなってしまいました。日々のメモを綴っていきます。

Entry Profile

Graphical FrontEnd Engineer
- Daisuke Takayama

MAD CITY 北九州市で生まれ育つ。20代はバンド活動に明け暮れ、ふと「webデザイナーになりたい。」と思い、デジタルハリウッド福岡校入学。卒業後、数々の賞を受賞、web業界をざわつかせる。
現在、主に、ゲーム制作中心に港区六本木界隈で活動中。

FOLLOW US