---
# System prepended metadata

title: Rocket Framework 入門 2 (Jsonレスポンス)
tags: [Responce, Rust, Json, Rocket]

---

###### 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


