【Axum 0.7.9】WindowsでAxum環境構築
Axum をWindows で利用する
この記事では、
Axum の概要
我が国ではこの著書が一つ有名なものと存じます。此書をきっかけにして、
「
余談
私事ですが、get
やpost
を単なる英単語としか認識していなかったことを鮮明に覚えています。
即ち⋯
そうした理解の上、未だ自信がないのであれば、私からは
Axum のチュートリアル
本記事で用いる
なぜ斯うも付属が多いのかと嘆息するを堪え、Usage example
とあるのを試すことと致します。
VSCode
開発環境としてのということで、
ここでは既に
rust-analyzer
Rust 開発の必需機能
rust-analyzer
です。私が感じた利点は次。
-
誤っている箇所が分かる
誤りを指摘されている様子
波線を引いて誤謬を強調される外、マウスカーソルを合わせることで、当該エラーメッセージを確認できるというものです。 -
適当な補完候補が分かる
候補が一覧される
通常にプログラムコードを書く際にも、誤りを訂正せんとする際にも言える事ですが、何の頼りもないのと、有効な候補から選択するのとでは、難易に大きな差があることは明白というもの。殊に、バージョン更新により互換性が失われた場合、候補の一覧からいち早く嫌な予感を察知できます。 -
データ型が分かる
データ型が表示される
は「型推論」を採用しているため、とりあえずRust let
と書けばよく、データ型を明記する必要がありません。型推論の明確な欠点として、プログラムコードを見ただけではデータ型が分からないことがあります。そうした欠点を補完して、プログラムの理解に供することができます。
なお、ファイルを開くだけでは機能しません。的外れなフォルダーを開いていても機能しません。rust-analyzer
は正しく動作しません。cargo new
で生成されるフォルダーを指します。
「フォルダーを開く」から
Postman
Web アプリケーションの動作確認
昨日初めて知りました。にわか仕込みの知識で高説上申候。
Postman
では、
その他にも同類の拡張機能としてREST Client
がありますし、一般のInsomnia
というものを推薦していますが、そちらは
Postman
の所感は次。
- ユーザー登録が求められる
拡張機能を利用するだけにしては仰々しいものだと感じましたが、Googleアカウントなどで登録すれば、特に操作もなく完了しました。 -
があるUI
キーボード入力を完全に省略するほどではありませんが、初めて知った私でも充分理解できました。一方で同じく拡張機能であるREST Client
は、.http
ファイルを作成し(🤔)、送信内容を手入力(🤔)する手法を取っているらしく、私は全然やりたくありませんでした。私が手入力の有用性に全く思い至らない間は、どのみち無用の長物でしょう。
PowerShell の環境変数
ls
が使えるという点です。dir
を入力し慣れない方なら、些細なストレス軽減になるでしょう。
さて、
例に、RUST_LOG
という環境変数にdebug
という値を定めます。この設定の直後、cargo run
でプログラムを実行します。
RUST_LOG=debug cargo run
$Env:RUST_LOG = "debug"
cargo run
cargo add
Cargo.toml
というファイルで管理されます。その方法は主に二つ。
- 直接編集する
-
cargo add
コマンドに委ねる
直接編集する場合は置いておいて、問題はcargo add
の場合にあります。
チュートリアルのCargo.toml
を見てみると、features
というものが見られます。
[dependencies]
axum = { path = "../../axum" }
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1.0", features = ["full"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
単にcargo add serde
などとした場合、features
の部分は反映されず、バージョン番号のみが書かれた状態になります。features
もコマンドで反映するためには、次のように記述することとなります。
cargo add serde --features derive
従って、全ての
cargo add axum
cargo add serde --features derive
cargo add tokio --features full
cargo add tracing
cargo add tracing-subscriber --features env-filter
実演手順
導入・インストールは終えたものとして、実演の手順を示します。
cargo new
package を作る
1. axum_example
名前に大文字を含めると文句を言われるので注意。
cargo new axum_example
axum_example
というフォルダーができるので、
以降は、全てaxum_example
での操作となります。cargo
コマンドは、Cargo.toml
の存在する位置でなければエラーになります。
tree
コマンドで確認すると次のように表示されました。target
フォルダーは中身が多くて邪魔なので、消した上での結果です。
PS C:\⋯\axum_example> rmdir .\target\
Confirm
The item at C:\⋯\axum_example\target\ has children and the Recurse parameter was not specified. If you continue, all children
will be removed with the item. Are you sure you want to continue?
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): y
PS C:\⋯\axum_example> tree /f
Folder PATH listing for volume OS
Volume serial number is ⋯
C:.
│ .gitignore
│ Cargo.lock
│ Cargo.toml
│
└───src
main.rs
cargo add
crate を追加する
2. cargo add axum
cargo add serde --features derive
cargo add tokio --features full
cargo add tracing
cargo add tracing-subscriber --features env-filter
main.rs
を編集する
3. axum_example/src/main.rs
が存在するので、これを編集します。
敢えて環境変数を確認するため、チュートリアルを次の通り改変しております。
use axum::{
http::StatusCode,
response::IntoResponse,
routing::{get, post},
Json,
Router,
serve
};
use serde::{Deserialize, Serialize};
use tokio::net::TcpListener;
use std::env;
// the input to our `create_user` handler
#[derive(Deserialize)]
struct CreateUser {
username: String,
}
// the output to our `create_user` handler
#[derive(Serialize)]
struct User {
id: u64,
username: String,
}
#[tokio::main]
async fn main() {
// initialize logging
let log_level: String = env::var("RUST_LOG").unwrap_or(String::from("info"));
println!("log_level: {log_level}");
env::set_var("RUST_LOG", log_level);
// initialize tracing
tracing_subscriber::fmt::init();
// build our application with a route
let app: Router =
Router::new()
// `GET /` goes to `root`
.route("/", get(root))
// `POST /users` goes to `create_user`
.route("/users", post(create_user));
// run our app with hyper
let listener: TcpListener = TcpListener::bind("127.0.0.1:3000").await.unwrap();
tracing::debug!("listening on {}", listener.local_addr().unwrap());
// serve app
serve(listener, app).await.unwrap();
}
// basic handler that responds with a static string
async fn root() -> &'static str {
"Hello, World"
}
async fn create_user(
// this argument tells axum to parse the request body
// as JSON into a `CreateUser` type
Json(payload): Json<CreateUser>,
) -> impl IntoResponse {
// insert your application logic here
let user: User = User {
id: 1337,
username: payload.username,
};
// this will be converted into a JSON response
// with a status code of `201 Created`
(StatusCode::CREATED, Json(user))
}
cargo run
プログラムを実行する
4. 環境変数RUST_LOG
の値をdebug
に定めます。
$Env:RUST_LOG = "debug"
cargo run
または、一行に纏めることもできます。
$Env:RUST_LOG = "debug"; cargo run
localhost
の3000
番で接続待機するようになります。
Postman
で確認する
5.
チュートリアルのプログラムは、GET
POST
// build our application with a route
let app: Router =
Router::new()
// `GET /` goes to `root`
.route("/", get(root))
// `POST /users` goes to `create_user`
.route("/users", post(create_user));
Postman
のメニューから、New HTTP Request
を選びます。
New HTTP Request
を選ぶ
GET
http://127.0.0.1:3000
を記述します。http://localhost:3000
でも可。
記述した後、Send
を選んで送信します。
URLを記述してSend
を選ぶ
この結果は、root
と実装された内容に基づいていると確認できます。
// basic handler that responds with a static string
async fn root() -> &'static str {
"Hello, World"
}
応答が表示される
ここでは、続けてPOST
に、http://127.0.0.1:3000/users
に変更します。.route("/users", post(create_user))
の"/users"
という定義によるものです。
POSTを選ぶ
URLを変更する
ここで、JSON
データを送信するため、Headers
メニューに記述を加えます。決まりなのでその通りに書くしかありません。
key | value |
---|---|
content-type | application/json |
Headersを編集する
Body
をraw
、JSON
に設定し、送信するJSON
データを手入力します。
rowからJSONを選ぶ
送信データの形式はCreateUser
として定められています。
// the input to our `create_user` handler
#[derive(Deserialize)]
struct CreateUser {
username: String,
}
ここでは、{"username": "Axum太郎"}
として送信します。
Sendを選ぶ
応答の型式はUser
として定められています。
// the output to our `create_user` handler
#[derive(Serialize)]
struct User {
id: u64,
username: String,
}
応答
1337
という数字が入っているのは、まさにcreate_user
による処理の結果です。
async fn create_user(
// this argument tells axum to parse the request body
// as JSON into a `CreateUser` type
Json(payload): Json<CreateUser>,
) -> impl IntoResponse {
// insert your application logic here
let user: User = User {
id: 1337,
username: payload.username,
};
// this will be converted into a JSON response
// with a status code of `201 Created`
(StatusCode::CREATED, Json(user))
}
Discussion