0Pricing
Learn Rust Coding · レッスン

Actix-web/RocketでREST APIを構築する

Actix-webやRocketなどの最新のRustウェブフレームワークを使い、ルート、リクエスト、レスポンスを扱うRESTful APIを開発します。

「Actix-web/RocketでREST APIを構築する」はCoddyKit上の無料Learn Rust Codingレッスンです。 これはレッスン1/3です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLearn Rust Coding学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Learn Rust Codingコースには全3レッスンが含まれています。

REST APIとは

REST(REpresentational State Transfer)は、ネットワークアプリケーションのアーキテクチャスタイルです。Webサービスがどのように通信すべきかを定めた原則の集合です。

RESTは、ステートレスでキャッシュ可能なWebサービスを構築し、標準的なHTTPメソッドでリソースを操作するためのガイドラインだと考えてください。

  • リソース:ユーザー、商品、注文など、名前を付けられるものすべてです。
  • URI:リソースを一意に識別する識別子です(例:/users/123)。
  • HTTPメソッド:リソースに対して実行する標準的な操作です(GET、POST、PUT、DELETE)。

WebサービスにRustを使う理由

RustにはWebサービス開発における独自の利点があり、高性能で信頼性の高いAPIを構築するための有力な選択肢です。

  • パフォーマンス:Rustのゼロコスト抽象化により、C/C++に匹敵することも多い、非常に効率的なコードを実現できます。
  • メモリ安全性:所有権システムが、ヌルポインタ参照やデータ競合などの一般的なバグを防ぎ、より堅牢なサービスにつながります。
  • 並行性:Rustのasync/awaitモデルは安全性の保証と組み合わせることで、並行Webサービスを「恐れずに」構築できます。
  • 信頼性:強力な型システムとコンパイル時チェックによって、多くのエラーを早期に検出できます。

Actix-webを知る

RustでWebサービスを構築する際は、フレームワークをよく利用します。Actix-webは、Rust向けの強力で実用的、かつ非常に高速なWebフレームワークです。

Actix-webはアクターフレームワークであるActixの上に構築されていますが、Actix-webを効果的に使うためにアクターを理解する必要はありません。非同期処理向けに設計されているため、多数のAPIリクエストを同時に処理するようなI/Oバウンドのタスクに適しています。

Actix-webには、ルーティング、リクエストとレスポンスの処理、ミドルウェアなどのためのツールが用意されており、複雑なAPIの作成を簡単にできます。

プロジェクトのセットアップと依存関係

まず、新しいRustプロジェクトを作成し、必要な依存関係を追加します。フレームワークにはactix-webを、JSONデータのシリアライズとデシリアライズにはserdeを使用します。

最初に、新しいプロジェクトを作成します。

cargo new my_rest_api --bin

次に、Cargo.tomlファイルの[dependencies]セクションに、次の行を追加します。

[dependencies]
actix-web = "4"
serde = { version = "1.0", features = ["derive"] }

最初のActix-webサーバー

最小構成のActix-webサーバーを書いてみましょう。このコードは、ポート8080で受信HTTPリクエストを待ち受ける基本構造を設定します。まだ特定のルートは処理しませんが、基盤となる部分です。

#[actix_web::main]マクロによって、async fn mainをActix-webのランタイムで実行できるようになります。

use actix_web::{App, HttpServer};

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    println!("Server running at http://127.0.0.1:8080");
    HttpServer::new(|| {
        // Our application instance, where we'll add routes
        App::new()
    })
    .bind(("127.0.0.1", 8080))? // Bind to an IP address and port
    .run() // Start the server
    .await // Await its completion
}

GETルートの定義

次に、サーバーへ単純なルートを追加しましょう。ルートは、受信したHTTPリクエストのパスとメソッド(GET /helloなど)を、特定のハンドラー関数に対応付けます。

ハンドラー関数hello_worldは、単に文字列を返します。web::get().to()によって、このハンドラーが/helloパスへのGETリクエスト用に登録されます。

use actix_web::{web, App, HttpServer, Responder};

// A handler function that returns a simple string response
async fn hello_world() -> impl Responder {
    "Hello, Actix-web!"
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    println!("Server running at http://127.0.0.1:8080");
    HttpServer::new(|| {
        App::new()
            // Register our route: GET /hello maps to hello_world()
            .route("/hello", web::get().to(hello_world))
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

動的ルートのパスパラメーター

APIでは、IDや名前など、URL内の動的な部分を処理する必要がよくあります。Actix-webでは、これらの値を取得するためにパスパラメーターを使用します。

ルートにプレースホルダー(例:/{name})を定義します。ハンドラーでは、web::Path<String>(またはデシリアライズ可能なその他の型)を使って値を取り出します。

use actix_web::{web, App, HttpServer, Responder};

// Handler function with a path parameter 'name'
async fn greet_name(name: web::Path<String>) -> impl Responder {
    format!("Hello, {}!", name.into_inner())
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    println!("Server running at http://127.0.0.1:8080");
    HttpServer::new(|| {
        App::new()
            // Route with a dynamic path segment for a name
            .route("/greet/{name}", web::get().to(greet_name))
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

POSTリクエストとJSONの処理

リソースを作成または更新する場合は、POSTまたはPUTリクエストを使用し、多くの場合、リクエストボディにJSON形式でデータを送信します。

Actix-webでは、web::Json<T>を使ってJSONを簡単に処理できます。想定するJSON構造に対応するRustのstructを定義し、serdeのDeserializeをderiveすると、Actix-webが受信したJSONを自動的に構造体へ解析します。

use actix_web::{web, App, HttpServer, Responder};
use serde::{Deserialize, Serialize};

// Define a struct to represent our incoming JSON data
#[derive(Deserialize, Serialize)]
struct User {
    username: String,
    email: String,
}

// Handler for POST requests that accepts a JSON User object
async fn create_user(user: web::Json<User>) -> impl Responder {
    // In a real app, you'd save this user to a database
    format!("User created: {} ({})", user.username, user.email)
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    println!("Server running at http://127.0.0.1:8080");
    HttpServer::new(|| {
        App::new()
            // POST /users expects a JSON body and maps to create_user()
            .route("/users", web::post().to(create_user))
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

状態を持つ単純なAPIの構築

これまでに学んだことを組み合わせて、ユーザーのリストをメモリ上で管理する小さなAPIを構築しましょう。web::Dataを使って、アプリケーション固有の状態(ユーザーリスト)を複数のハンドラー間で共有します。

std::sync::Mutexを使うことで、複数の同時リクエストからVec<User>へ安全に変更アクセスできるようにします。GET /usersとPOST /usersのエンドポイントを用意します。

use actix_web::{web, App, HttpServer, Responder, HttpResponse};
use serde::{Deserialize, Serialize};
use std::sync::Mutex; // For shared mutable state

// Define a User struct that can be serialized/deserialized and cloned
#[derive(Deserialize, Serialize, Clone)]
struct User {
    id: u32,
    username: String,
    email: String,
}

// Application state to hold our users and track next ID
struct AppState {
    users: Mutex<Vec<User>>,
    next_id: Mutex<u32>,
}

// Handler to get all users
async fn get_users(data: web::Data<AppState>) -> impl Responder {
    let users = data.users.lock().unwrap(); // Acquire a lock
    web::Json(users.clone()) // Return users as JSON
}

// Handler to create a new user
async fn create_user(
    data: web::Data<AppState>,
    new_user: web::Json<User>,
) -> impl Responder {
    let mut users = data.users.lock().unwrap();
    let mut next_id = data.next_id.lock().unwrap();

    let user = User {
        id: *next_id,
        username: new_user.username.clone(),
        email: new_user.email.clone(),
    };
    users.push(user.clone());
    *next_id += 1; // Increment for the next user
    HttpResponse::Created().json(user) // Return 201 Created status and user
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    println!("Server running at http://127.0.0.1:8080");
    // Create shared application state
    let app_state = web::Data::new(AppState {
        users: Mutex::new(vec![]), // Initialize with an empty user list
        next_id: Mutex::new(1),    // Start IDs from 1
    });

    HttpServer::new(move || { // 'move' closure to capture app_state
        App::new()
            .app_data(app_state.clone()) // Register shared state with the app
            .route("/users", web::get().to(get_users))
            .route("/users", web::post().to(create_user))
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

API概念のクイックチェック

基本的なActix-webサーバーのセットアップと、さまざまなHTTPリクエストの処理方法を学びました。理解度を確認しましょう。

振り返りと次のステップ

よくできました。RustとActix-webでRESTful APIを構築するための第一歩を踏み出しました。

  • REST APIの基本と、Rustが適している理由を学びました。
  • 基本的なActix-webプロジェクトのセットアップ方法を学びました。
  • GETとPOSTのルート定義について扱いました。
  • パスパラメーターの取り出し方とJSONペイロードの処理方法を確認しました。
  • 最後に、web::Dataを使ってメモリ上の状態を管理する単純なAPIを構築しました。

次は、データベースとの統合と堅牢なエラー処理についてさらに学び、より強力で本番環境に対応できるWebサービスを構築しましょう。

よくある質問

「Actix-web/RocketでREST APIを構築する」レッスンは無料ですか?

はい。「Actix-web/RocketでREST APIを構築する」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Learn Rust Codingコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Learn Rust Codingコースには全3レッスンが含まれています。

「Actix-web/RocketでREST APIを構築する」で何を学びますか?

Actix-webやRocketなどの最新のRustウェブフレームワークを使い、ルート、リクエスト、レスポンスを扱うRESTful APIを開発します。 ブラウザで直接実行するハンズオンコードでLearn Rust Codingを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Learn Rust Codingを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのLearn Rust Codingは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/3です。

「Actix-web/RocketでREST APIを構築する」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このLearn Rust Codingレッスンでコードを書いて実行できますか?

はい。すべてのLearn Rust Codingレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Actix-web/RocketでREST APIを構築する
  2. データベース連携(SQLx/Diesel)
  3. 認証と認可
← Learn Rust Codingに戻る