はじめに
前回、Rustの環境構築をしたので今回はサーバーを実装します。
単純なAPIサーバーとして以下の実装をしていきます。
- GET
/system/ping
でpongを返す -
POST
/system/ping
で{"ping" : "value"}
を送ると、{"pong" : "value"}
を返す
Tideの起動
Tideを動かしてみます。
任意の場所でプロジェクトを作ります。
% cargo new example-tide
% cd example-tide
Cargo.tomlのdependenciesに以下を追記します。
[dependencies]
tide = "0.13.0"
async-std = { version = "1.6.0", features = ["attributes"] }
main.rsを以下に変更します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// app.listen()がエラーを返す可能性があるのでResult型を受け付けるようにする | |
#[async_std::main] | |
async fn main() -> Result<(), std::io::Error> { | |
// ログ記録開始 | |
tide::log::start(); | |
// インスタンス生成 | |
let mut app = tide::new(); | |
// ルーティングとHTTPメソッドを設定し、何をするか決める | |
app.at("/").get(|_| async { Ok("Hello, world!") }); | |
// webサーバーがどのIPアドレス、ポートで受け付けるか設定する | |
app.listen("127.0.0.1:8080").await?; | |
// 何もなければOkでタプルを返す | |
Ok(()) | |
} |
ここまでできたらcargo runします。
試しにcurlしてみましょう。
% curl localhost:8080
Hello, world!
Webサーバーの起動に成功しました。
「GET /system/pingでpongを返す」を実装
以下のように5行目を変更します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#[async_std::main] | |
async fn main() -> Result<(), std::io::Error> { | |
tide::log::start(); | |
let mut app = tide::new(); | |
app.at("/system/ping").get(|_| async { Ok("pong") }); | |
app.listen("127.0.0.1:8080").await?; | |
Ok(()) | |
} |
curlしてみましょう。
% curl localhost:8080/system/ping
pong
できましたが、APIサーバーとしては扱いやすいようにjsonで返したいです。
Rustでjsonといえばserde_jsonですが、Tideはすでにjson macroを持っています。
ですので、serde_jsonを使わずともjsonを返すことが可能です。
以下のように5行目を変更します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use tide::prelude::*; | |
#[async_std::main] | |
async fn main() -> Result<(), std::io::Error> { | |
tide::log::start(); | |
let mut app = tide::new(); | |
app.at("/system/ping").get(|_| async { Ok(json!({"ok" : "pong"})) }); | |
app.listen("127.0.0.1:8080").await?; | |
Ok(()) | |
} |
curlしてみましょう。
% curl localhost:8080/system/ping
{"ok":"pong"}
jsonで返すことができました。
「POST /system/ping
で{"ping" : "value"}
を送ると、{"pong" :
"value"}
を返す」を実装する
6行目にPOSTを受け付ける記述を追記します。(この時点ではPOSTパラメータを無視しています)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use tide::prelude::*; | |
#[async_std::main] | |
async fn main() -> Result<(), std::io::Error> { | |
tide::log::start(); | |
let mut app = tide::new(); | |
app.at("/system/ping").get(|_| async { Ok(json!({"ok" : "pong"})) }); | |
app.at("/system/ping").post(|_| async { Ok(json!({"ok" : "pong"})) }); | |
app.listen("127.0.0.1:8080").await?; | |
Ok(()) | |
} |
curlしてみましょう。
% curl -XPOST localhost:8080/system/ping -d '{"ping":"value"}'
{"ok":"pong"}
やった!POSTで受付に成功しています。
それではPOSTパラメータを受け取り、値を返すようにします。
まずはserdeとserde_jsonをdependenciesに追加します。
[dependencies]
tide = "0.13.0"
async-std = { version = "1.6.0", features = ["attributes"] }
serde = "1.0.114"
serde_json = "1.0"
serdeは構造体をSerialize、Deserializeする時に使います。これで構造体を簡単にjsonにすることができます。(ここはもしかしたらTideがやってくれる...?)
以下のようにmainを修正します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use tide::prelude::*; | |
use serde::{Deserialize, Serialize}; | |
use tide::Request; | |
#[async_std::main] | |
async fn main() -> Result<(), std::io::Error> { | |
tide::log::start(); | |
let mut app = tide::new(); | |
app.at("/system/ping").get(|_| async { Ok(json!({"ok" : "pong"})) }); | |
// requestを受け取って関数({}の中)に渡します | |
app.at("/system/ping").post(|mut request: Request<()>| async move { | |
// requestをjson形式にし、Ping型にします | |
let body: Ping = requet.body_json().await?; | |
// Ping型からpingの値だけを使い、Pong型にします | |
let res: Pong = Pong { pong: body.ping }; | |
// Pong型のresをjsonで返します | |
Ok(json!(&res)) | |
}); | |
app.listen("127.0.0.1:8080").await?; | |
Ok(()) | |
} | |
// 受取用の構造体 | |
#[derive(Debug, Deserialize, Serialize)] | |
struct Ping { ping: String } | |
// 返却用の構造体 | |
#[derive(Debug, Deserialize, Serialize)] | |
struct Pong { pong: String } |
curlしてみましょう。
% curl -XPOST localhost:8080/system/ping -d '{"ping":"value"}'
{"pong":"value"}
できました!
おわりに
今回はTideでルーティング、GETとPOSTができるようになりました。
次回は、ちゃんとResponseを返す(ステータスコードなど)ところまでやりたいと思います。
0 件のコメント:
コメントを投稿