諸注意
- Rust超初心者です。お手柔らかにお願いします。
- いつもはpythonとC++を使うことが多いですが、Rust書いてみたかったので触ってみました。
やったこと
- とりあえずいろんなパターンのAPIエンドポイントを書いてみました。(pythonのflaskみたいにかけるのか調べてみたかった。)
- そして、それを呼ぶ簡単な呼び出しコードを、reqwestを使って書いてみました(pythonのrequestsみたいな)。
rustの環境
$ rustc --version
rustc 1.40.0-nightly (1423bec54 2019-11-05)
感想
- Ironは本家gitのexampleが充実してないような気がしました。
- formからパラメータを貰うところができずに詰んで、とりあえず一旦終了しました。
- Rocketというフレームワークをあるのを知って、そっちの方が簡単に見えるのでそっちも試してみることにした(<=今ここ)
とりあえず、チュートリアルの段階で詰まるのが一番きついと思うので、しょうもない記事ですが誰かの役に立てばいいと思ってます。
動かしてみて動いたコードだけを貼っていきます。
もっと勉強してRust記事更新していきます。
「いいね」や「コメント」お待ちしております!!
Cargo.toml
[package]
.....
[dependencies]
rustc-serialize="*"
router = "0.6.0"
handlebars-iron = "0.27"
staticfile = "*"
mount = "*"
handlebars = "0.20.5"
urlencoded = "0.5.0"
params="*"
[dependencies.iron]
version="0.6"
src/main.rs
最初のインポートの部分
extern crate iron;
extern crate router;
extern crate staticfile;
extern crate mount;
extern crate params;
extern crate urlencoded;
use std::io::Read;
use iron::prelude::*;
use iron::status;
use router::Router;
use router::url_for;
// use staticfile::Static;
// use mount::Mount;
use std::error::Error;
use rustc_serialize::json;
use iron::headers::ContentType;
use handlebars_iron as hbs;
use hbs::{DirectorySource, HandlebarsEngine, Template};
use std::collections::HashMap;
// use std::path::Path;
// use urlencoded::UrlEncodedBody;
// use params::Params;
main.rs
fn main() {
//ルーティングは、Router クラスのオブジェクトを呼び出して、.get()メソッドなどで追加できる。
// 引数の1つ目はエンドポイント、2つ目は呼ばれる関数、3つ目はurl_for()とかで呼ばれる名前。
let mut router = Router::new();
//hello world のストリングを返すエンドポイント
router.get("/hello", hello, "hello");
//postでストリングをもらって、 Hello "なんとか"と返すエンドポイント
router.post("/hello_prefix", hello_prefix, "hello_prefix");
//決められたjsonを返すエンドポイント
router.get("/json", json, "json");
//もらったストリングからjsonを返すエンドポイント
router.post("/json_custom", json_custom, "json_custom");
//template テンプレートを表示するエンドポイント
router.get("/template_test", template_test, "template_test");
//結局エラーが解決できなかったエンドポイント
// router.get("/form", top_handler, "index");
// router.post("/greet", greet_handler, "greeting");
// 下のIron::new()のところで、Iron::new(router) としても良いけど、テンプレートを使うときはchainクラスで
// router とHandlebarsEngineをラップしたものを渡す。
let mut chain = Chain::new(router);
// それぞれのテンプレートディレクトリたちをIronに教える。
let mut hbse = HandlebarsEngine::new();
hbse.add(Box::new(DirectorySource::new("./templates/", ".html")));
hbse.add(Box::new(DirectorySource::new("./static/js/", ".js")));
hbse.add(Box::new(DirectorySource::new("./static/css/", ".css")));
if let Err(r) = hbse.reload() {
panic!("{}", r.description());
}
chain.link_after(hbse);
//ホストを決めて、Ironフレームワークを起動する。
let host = "localhost:8080";
println!("binding on {}", host);
Iron::new(chain).http(host).unwrap();
//辞書型みたいなものを作るデフォ関数
fn create_default_data() -> HashMap<String, String> {
HashMap::new()
}
//hello エンドポイントで呼ばれる関数
fn hello(_: &mut Request) -> IronResult<Response> {
Ok(Response::with((status::Ok, "Hello World!")))
}
//hello_prefix エンドポイントで呼ばれる関数
//ちなみに.to_string()はストリングを静的から動的にする関数。
fn hello_prefix(req: &mut Request) -> IronResult<Response> {
let mut body = String::new();
req.body.read_to_string(&mut body)
.expect("Failed to read line");
let res = "Hello ".to_string() + &body + &"!".to_string();
Ok(Response::with((status::Ok, res)))
}
//json エンドポイントで呼ばれる関数
fn json(_: &mut Request) -> IronResult<Response>{
let letter = Letter{
title: "PPAP".to_string(),
message: "i have a pen, i have an apple.".to_string()
};
let payload = json::encode(&letter).unwrap();
Ok(Response::with((ContentType::json().0, status::Ok, payload)))
}
//json_custom エンドポイントで呼ばれる関数
fn json_custom(req: &mut Request) -> IronResult<Response> {
let mut body = String::new();
req.body.read_to_string(&mut body).expect("failed to read line");
let letter = Letter{
title: body,
message: "i got this".to_string()
};
let payload = json::encode(&letter).unwrap();
Ok(Response::with((ContentType::json().0, status::Ok, payload)))
}
//template_test エンドポイントで呼ばれる関数
fn template_test(_: &mut Request) -> IronResult<Response> {
let mut resp = Response::new();
let data = create_default_data();
resp.set_mut(Template::new("index", data)).set_mut(status::Ok);
Ok(resp)
}
}
// htmlのフォームをpostした時にそれを受け取りたかったが、Paramsのgit(https://github.com/iron/params)に載っている
// example コード(下)を実行すると、のようなエラーが出て、解決できなかった。
// 引き続き調査中。
// fn main(){
// let mut mount = Mount::new();
// mount.mount("/", Static::new(Path::new("static/index.html")));
// // mount.mount("/index.js", Static::new(Path::new("static/index.js")));
// Iron::new(mount).http("localhost:3000").unwrap();
// }
reqwest を使ってリクエストを送ってみる。
Cargo.toml
[dependencies]
reqwest="*"
main.rs
extern crate reqwest;
use std::io;
use std::collections::HashMap;
fn main() {
//クライアントオブジェクトを作る。
let client = reqwest::Client::new();
//#####################################################################
// hello エンドポイントにリクエスト送信してみる。
let mut resp = reqwest::get("http://localhost:8080/hello").unwrap();
if resp.status().is_success() {
println!("success!");
} else if resp.status().is_server_error() {
println!("server error!");
} else {
println!("Something else happened. Status: {:?}", resp.status());
}
resp.copy_to(&mut io::stdout()).unwrap();
println!("\n");
//#####################################################################
// hello_prefix エンドポイントにリクエスト送信してみる。
let mut res = client.post("http://localhost:8080/hello_prefix")
.body("waiwaiwaiwai".to_string())
.send().unwrap();
if res.status().is_success() {
println!("success!");
} else if res.status().is_server_error() {
println!("server error!");
} else {
println!("Something else happened. Status: {:?}", res.status());
}
res.copy_to(&mut io::stdout()).unwrap();
println!("\n");
//#####################################################################
// json_custom エンドポイントにリクエスト送信してみる。
let mut map = HashMap::new();
map.insert("lang", "rust");
map.insert("body", "json");
let mut res = client.post("http://localhost:8080/json_custom")
.json(&map)
.send().unwrap();
if res.status().is_success() {
println!("success!");
} else if res.status().is_server_error() {
println!("server error!");
} else {
println!("Something else happened. Status: {:?}", res.status());
}
res.copy_to(&mut io::stdout()).unwrap();
println!("\n");
}