🦀
RustのTokio製WEBフレームワークaxum version 0.5.6 を使ってみた
概要
axum
のversion【0.5.6】を使ってみました!
今回は、フロントから渡されてきた値を取得するために、以下4パターンの値抽出方法を実装しました。
①BodyのJSON値
②Query
③Path
④QueryとPath両方
上記4パターンの実装に関して、①から順番に記述します。
Cargo.tomlは以下のようになります。
Cargo.toml
[package]
name = "example"
version = "0.1.0"
edition = "2021"
[dependencies]
reqwest = "0.11"
axum = "0.5.6"
tokio = { version = "1", features = ["full"] }
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
コードを参考にする場合はバージョンによる違いにご注意ください。
バージョンが違うと動かない場合があります。
実践①フロントから送るBodyのJSON値を抽出
main.rs
use axum::{
routing::{post},
Router,
response::Json
};
use serde_json::{Value, json};
#[tokio::main]
async fn main() {
let app = Router::new()
.route("/api", post(get_body_json_user_id));
// localhost:3000 で hyper と共に実行する
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
.serve(app.into_make_service())
.await
.unwrap();
}
// body_jsonからuser_idを取得
async fn get_body_json_user_id(body_json: Json<Value>) -> Json<Value> {
// user_idの取得
let user_id = match body_json.0.get("user_id") {
Some(user_id) => user_id,
None => panic!("error")
};
Json(json!({ "user_id": user_id }))
}
リクエスト内容
実践② Queryから値を抽出
main.rs
use axum::{
routing::get,
Router,
response::Json,
extract::{Query}
};
use serde::{Serialize, Deserialize};
use serde_json::{Value, json};
use std::collections::HashMap;
#[tokio::main]
async fn main() {
let app = Router::new()
.route("/api", get(get_query_user_id));
// localhost:3000 で hyper と共に実行する
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
.serve(app.into_make_service())
.await
.unwrap();
}
#[derive(Debug, Deserialize, Serialize)]
struct GetUserIdParams {
user_id: String,
}
// queryからuser_idを取得
async fn get_query_user_id(Query(params): Query<HashMap<String, String>>) -> Json<Value> {
let user_id = match params.get("user_id") {
Some(user_id) => user_id,
None => panic!("error")
};
Json(json!({ "user_id": user_id }))
}
リクエスト内容
実践③Pathから値を取得
main.rs
use axum::{
routing::get,
Router,
response::Json,
extract::{Path}
};
use serde::{Serialize, Deserialize};
use serde_json::{Value, json};
#[tokio::main]
async fn main() {
let app = Router::new()
.route("/api/:user_id", get(get_path_user_id));
// localhost:3000 で hyper と共に実行する
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
.serve(app.into_make_service())
.await
.unwrap();
}
#[derive(Debug, Deserialize, Serialize)]
struct GetUserIdPath {
user_id: String,
}
// pathからuser_idを取得
async fn get_path_user_id(Path(path): Path<GetUserIdPath>) -> Json<Value> {
let user_id = path.user_id;
Json(json!({ "user_id": user_id }))
}
リクエスト内容
実践④ QueryとPath両方から値を抽出
main.rs
use axum::{
routing::get,
Router,
response::Json,
extract::{Path,Query}
};
use serde::{Serialize, Deserialize};
use serde_json::{Value, json};
#[tokio::main]
async fn main() {
let app = Router::new()
.route("/api/users/:user_id/home", get(get_query_and_path_user_id));
// localhost:3000 で hyper と共に実行する
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
.serve(app.into_make_service())
.await
.unwrap();
}
#[derive(Debug, Deserialize, Serialize)]
struct ExamplePath {
user_id: String,
}
#[derive(Debug, Deserialize, Serialize)]
struct ExampleQuery {
search_text: String,
}
// デフォルト値の設定
impl Default for ExampleQuery {
fn default() -> Self {
Self { search_text: String::from("") }
}
}
// QueryとPathから値を抽出
async fn get_query_and_path_user_id(
Path(path): Path<ExamplePath>,
example_query: Option<Query<ExampleQuery>>,
) -> Json<Value> {
let user_id = path.user_id;
// unwrap_or_default: Okの場合値を返し、Errの場合値の型のデフォルトを返す
let Query(example_query) = example_query.unwrap_or_default();
Json(json!({ "user_id": user_id, "search_text": example_query.search_text }))
}
リクエスト内容
最後に
コードの書き方は、doc.rsを参考にしました。
なお、doc.rsでは、URLの【】部分のバージョンを書き換えることで、自分が見たいバーションのドキュメントを見ることができます。
// 例
https://docs.rs/axum/【0.5.6】/axum/extract/index.html
// 実際のURL
https://docs.rs/axum/0.5.6/axum/extract/index.html
Discussion