LoginSignup
2
1

More than 3 years have passed since last update.

[Rust]tide0.13.0でHTMLを表示するサンプル

Last updated at Posted at 2020-04-23

変更

2020/6/8

tide: 0.10.0にて、静的htmlをレスポンスとして返すメソッドが追加されました。
これに伴い、記事の内容を

  • 静的htmlをレスポンスとして返すサンプル
  • htmlテンプレートを使ってレスポンスを作成するサンプル

に変更します。

注意

tideは2020/6/8時点で開発中です。
プロダクトでの使用はおすすめしません。
tidev0.13.0で公式リポジトリから注意文が消えました。

環境

  • OS: Windows10 2004
  • Rust:
    • Toolchain: stable-x86_64-pc-windows-msvc unchanged
    • rustup: 1.22.1
    • rustc: 1.45.2
    • cargo: 1.45.1
  • tide: 0.13.0

サンプル

静的htmlファイル

静的なhtmlファイルはBody::from_file("*.html")でhtml用のレスポンスとして読み込まれる。

static_html
let mut res = tide::Response::new(StatusCode::Ok);
let body = Body::from_file("filename.html").await?;
res.set_body(body);

htmlテンプレートエンジン

(大体のhtmlテンプレートエンジンで文字列型を返すと思うので)
レスポンスのボディーを Body::from_string() で作って、メディアタイプをhtmlに変更する。

template
let mut res = tide::Response::new(StatusCode::Ok);

// generate_html()は自作の関数です。
// htmlテンプレートエンジンからhtmlをString型で返す関数として読み替えてください。
let html_body = generate_html("param").unwrap();
let body = Body::from_string(html_body);
res.set_body(body);

// Body::from_string()だと、レスポンスがプレーンテキストとして認識されるので、
// mime::HTMLを設定しなおさなければならない。
res.set_content_type(mime::HTML);

メディアタイプについては、以下を参照
https://developer.mozilla.org/ja/docs/Web/HTTP/Basics_of_HTTP/MIME_types

コード

cargo.toml(折りたたんでいます)
cargo.toml
# 省略

[dependencies]
tide = "0.13"

# htmlの生成に使用
tinytemplate = "1.1"
serde = "1.0"

[dependencies.async-std]
version = "1.6"
features = ["attributes"]

main.rs(折りたたんでいます)
main.rs
use tide::http::{mime, StatusCode};
use tide::Body;

#[async_std::main]
async fn main() -> Result<(), std::io::Error> {
    let mut app = tide::new();

    app.at("/").get(hello);
    app.at("/hello_html").get(hello_html);
    app.at("/html_template/:name").get(hello_html_from_template);
    app.at("/*").get(not_found);
    app.listen("127.0.0.1:8080").await?;
    Ok(())
}

async fn hello(_req: tide::Request<()>) -> Result<String, tide::Error> {
    Ok("hello".to_string())
}

async fn hello_html(_req: tide::Request<()>) -> Result<tide::Response, tide::Error> {
    let mut res = tide::Response::new(StatusCode::Ok);

    // hello.htmlを作成してプロジェクトルートにおいてください。
    // githubからクローンしている場合には、そのままで問題ありません。
    let body = Body::from_file("hello.html").await?;
    res.set_body(body);
    Ok(res)
}

async fn not_found(_req: tide::Request<()>) -> Result<tide::Response, tide::Error> {
    let mut res = tide::Response::new(StatusCode::NotFound);
    let body = Body::from_string("Not Found".to_string());
    res.set_body(body);
    Ok(res)
}

async fn hello_html_from_template(req: tide::Request<()>) -> Result<tide::Response, tide::Error> {
    let mut res = tide::Response::new(StatusCode::Ok);

    // 'tide::Server.at(*/:name)'の形でルーティングしている場合に、:nameの値を取得する
    let name = req.param::<String>("name")?;

    let html_body = generate_html(name).unwrap();
    let body = Body::from_string(html_body);
    res.set_body(body);
    res.set_content_type(mime::HTML);
    Ok(res)
}


// htmlをテンプレートエンジンで生成します。
use serde::Serialize;
use std::error::Error;
use tinytemplate::TinyTemplate;

#[derive(Serialize)]
struct Context {
    name: String,
}

const HTML_TEMPLATE: &'static str = "<!DOCTYPE html>
    <html lang=\"en\">
        <head>
            <meta charset=\"UTF-8\">
            <title>Hello!</title>
        </head>
        <body>
            <h1>Hello!</h1>
            <p>Hi {name} from Rust</p>
        </body>
    </html>";

pub fn generate_html(name: String) -> Result<String, Box<dyn Error>> {
    let mut template = TinyTemplate::new();
    template.add_template("hello_rust_template", HTML_TEMPLATE)?;

    let context = Context { name };

    let rendered = template.render("hello_rust_template", &context)?;
    Ok(rendered)
}

Githubリポジトリ

最後に

Web周りの知識がほとんどないので、間違っているところも多いと思います。
間違っている部分があれば、ご連絡いただけると幸いです。

参考文献

curl コマンド 使い方メモ
MDN Web Docs MIME タイプ (IANA メディアタイプ)
Don't Repeat Yourself tide 0.7.0 を試してみる
DOCS.RS tide

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1