###### tags: `Rust` `Rocket` `Responce` `Json` # Rocket Framework 入門 2 (Jsonレスポンス) # Responces Rocketのhttpレスポンスについて理解する。 httpハンドラの戻り値は任意の型が許されているが、Responder Trait が 実装されていなければならない # Reponder Response の実体は rocket::Response 型 の構造体 Responderトレイト - respond_to(self, &request)->response::Result を実装 - 戻り値は2種類 - Ok(Response) - Err(Status) ## 最初から実装されてるResponderトレイト 標準ライブラリにあるいくつかの型は、Rocketにより 最初からResponderが実装されてる - &str : Content-Type: text/plane - String - &[u8] : Content-Type: application/octet-stream - Vec\<u8> - File - () # WrappingResponder Rocketが用意するResponder構造体 Responderを実装する構造体をラップすることで、 - レスポンスをJson化する - ステータスコードを付与する ## status モジュール rocket::response::status 下の例は 202 Accepted のステータスコードでレスポンスするコード ```rust= use rocket::response::status; #[post("/<id>")] fn new(id: usize) -> status::Accepted<String> { status::Accepted(Some(format!("id: '{}'", id))) } ``` ## contentモジュール rocket::response::content 下の例は、stringで書いたjsonを、Json\<T>でラップしたもの ```rust= use rocket::response::content; #[get("/")] fn json() -> content::Json<&'static str> { content::Json("{ 'hi': 'world' }") } ``` ## Error : Responderが失敗する場合 Responderがレスポンスを生成するのに失敗した場合、 ステータスコードともに Err を返す。 error catcher に回す。 500errorを返す ## Status 失敗したとき、Statusコードだけ返す場合が多い rocket::http::Status Statusタイプの戻り値として返す ```rust= use rocket::http::Status; #[get("/")] fn just_fail() -> Status { Status::NotAcceptable } ``` # Rocket Responder rocket::response モジュール Rocketが提供しているResponderオブジェクト - Content - NamedFile - Redirect - Stream - status - Json - MsgPack - Template ## Stream 大量のデータをクライアントに送る必要があるとき、データをストリームするのが クライアントのメモリを圧迫しないためのベターな選択となる。 ```rust= #[get("/stream")] fn stream() -> io::Result<Stream<UnixStream>> { UnixStream::connect("/path/to/my/socket").map(|s| Stream::from(s)) } ``` ## JSON rocket_contribに含まれるJson Responderにより、レスポンスが可能 Json\<T>の T に任意の構造体型を指定することで、Jsonにシリアライズ できるようになる。 T 型は **serde** クレートの Serialize トレイトをderiveされている必要がある。 ```rust= use rocket_contrib::json::Json; #[derive(Serialize)] struct Task { ... } #[get("/todo")] fn todo() -> Json<Task> { ... } ``` ## Templates Rocketは、組み込みのテンプレートエンジンをサポートしている。 rocekt_contribに含まれる Template Responder によって 実装される。 "index" という名前のテンプレートを返す場合、以下のように書く ```rust= #[get("/")] fn index() -> Template { let context = /* object-like value */; Template::render("index", &context) fn main() { rocket::ignite() .mount("/", routes![...]) .attach(Template::fairing()); } ``` contextは、objectライクな値を代入する "index" テンプレートに値を埋め込んで返す。 また、テンプレートを使う際は .attach(Template::fairing())を rocketオブジェクトで実行する。 # rocket_contrib Rocketが使用しているcoreパッケージを まとめたクレート - json - serve - msgpack - handlebars_templates - tera_templates - uuid - &{database}_pool - helmet