この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
What is actix?
actixとは、Rust製のActorフレームワークです。
(Java/Scalaでいうと、Akkaがメジャーですね)
アクター同士が非同期でメッセージをやり取りし、安全に並行処理を行うことができます。
そのactixをベースとしてWeb開発用機能を追加したのが、
軽量・高速なWeb開発フレームワークであるactix-webです。
actix-webで開発されたアプリは、実行ファイルにHTTPサーバーを含んでいるため、
そのまま使うこともできるし、apacheやnginxの後ろに置くこともできます。
Environment
今回使用した動作環境は以下のとおりです。
- OS : MacOS X 10.15.1
- Rust : 1.42.0
※actix-webはRust 1.39以降で動作します
Setup Rust & actix-web
※Rustのインストール方法についてはこちらもご覧ください
ではRustをインストールしてサンプルプロジェクトをつくってみましょう。
まずはrustup(Rustのインストーラ)をインストールします。
% curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
↑のコマンドでインストール後、terminalを再起動したら、問題ないか確認。
% rustup -V
rustup 1.21.1 (7832b2ebe 2019-12-20)
Rustが1.39以降でないなら、uddateします。
% rustup update
Rustのバージョンも更新されました。
%rustc --version
rustc 1.42.0 (b8cedc004 2020-03-09)
Cargoを使ってプロジェクトを作成します。
% cargo new actix-sample
Created binary (application) `actix-sample` package
actix-example/Cargo.tomlで依存ライブラリ(actix-webとactix-rt)を設定します。
[package]
name = "actix-sample"
version = "0.1.0"
authors = ["・・・・・"]
edition = "2018"
[dependencies]
actix-web = "2.0"
actix-rt = "1.0"
src/main.rsを編集。3000番ポートでHTTPサーバが起動するようにします。
use actix_web::{web, App, HttpResponse, HttpServer, Responder};
async fn index() -> impl Responder {
HttpResponse::Ok().body("Hello world!")
}
async fn index2() -> impl Responder {
HttpResponse::Ok().json("{\"message\":\"Hello world again!\"}")
}
#[actix_rt::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.route("/", web::get().to(index))
.route("/again", web::get().to(index2))
})
.bind("127.0.0.1:8088")?
.run()
.await
}
runコマンドでアプリを起動しましょう。
http://localhosat:3000にアクセスすれば、Hello Worldが表示されます。
http://localhosat:3000/againにアクセスすれば、json形式でレスポンスが返されます。
% cargo run
とてもシンプルなプログラムですが、ソースのポイントをいくつか説明します。
- index/index2関数
パスと紐付けるためのリクエストハンドラを作成しています。
これはHttpRequestを受け取り(optional)、Responderをimplimentsした非同期関数となります。
- main関数
Appインスタンスを作成し、パスとリクエストハンドラを登録します。
そしてHttpServerでAppインスタンスを使用し、8088番ポートで起動します。
なお、ここでは、main関数に、actix_rt::mainマクロを記述しています。
(Actixに実行される非同期関数をマークするためのマクロ)
そして、main関数にもasyncをつけます。
※ async/awaitについてはこのへん参照
新しくパスを追加してみましょう。
今度はgetマクロを使ってハンドラを定義します。
・・・
use actix_web::get;
#[get("/macro-path")]
async fn index3() -> impl Responder {
HttpResponse::Ok().body("response from index3!")
}
・・・
service関数でindex3を追加しましょう。
他のハンドラよりさらにシンプルに追加できました。
・・・
#[actix_rt::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.route("/", web::get().to(index))
.route("/again", web::get().to(index2))
.service(index3) // これを追加
})
.bind("127.0.0.1:8088")?
.run()
.await
}
まとめ
とりあえずactix-webを動かすことはできました。
基本的な解説はここにありますし、
Gihubにはいろいろなactix-webのサンプルプログラムもありますので、
これらを参考にしてみてください。