###### tags: `Rust` `Rocket` `Fairing`
# Rocket Framework 入門 3
arbitrary = optional = 任意の
# Fairings
Fairing自体は、トレイトである。
Fairingトレイトを実装した構造体が、ミドルウェアとして
rocektオブジェクトにアタッチできる
Fairingsは、rocketの middleware アプローチ
rocketのライフサイクルに追加処理を組み込める
- Request/Responce情報の記録・書き換え
- ベンチマーク計測
## できること・できないこと
できること
- 条件により、アプリの起動をしない
- アプリの設定を取得・検証・修正できる
できないこと
- リクエストを直接中断したり、レスポンスしたりできない
- 任意に挿入できるわけではなく、request以外のデータをrequestに入れたりできない
# Fairingsを使う
## Rocketオブジェクトにattach
```rust=
rocket::ignite()
.attach(req_fairing)
.attach(res_fairing)
.launch();
```
## 4種類のfairing
- Attach(on_attach) : アタッチされたとき実行。初期設定の書き換えなど
- Launch(on_launch) : サーバーが起動したとき実行
- Request(on_request) : リクエストが来たとき実行
- Response(on_response) : レスポンスをするとき実行
## 実装例
```rust=
struct Counter {
get: AtomicUsize,
post: AtomicUsize,
}
impl Fairing for Counter {
// This is a request and response fairing named "GET/POST Counter".
fn info(&self) -> Info {
Info {
name: "GET/POST Counter",
kind: Kind::Request | Kind::Response
}
}
// Increment the counter for `GET` and `POST` requests.
fn on_request(&self, request: &mut Request, _: &Data) {
match request.method() {
Method::Get => self.get.fetch_add(1, Ordering::Relaxed),
Method::Post => self.post.fetch_add(1, Ordering::Relaxed),
_ => return
}
}
fn on_response(&self, request: &Request, response: &mut Response) {
// Don't change a successful user's response, ever.
if response.status() != Status::NotFound {
return
}
// Rewrite the response to return the current counts.
if request.method() == Method::Get && request.uri().path() == "/counts" {
let get_count = self.get.load(Ordering::Relaxed);
let post_count = self.post.load(Ordering::Relaxed);
let body = format!("Get: {}\nPost: {}", get_count, post_count);
response.set_status(Status::Ok);
response.set_header(ContentType::Plain);
response.set_sized_body(Cursor::new(body));
}
}
}
```
## hook
クロージャーを使って、簡単に実装できる
rocket::fairing::AdHoc のリファレンスを参照
```rust=
use rocket::fairing::AdHoc;
use rocket::http::Method;
rocket::ignite()
.attach(AdHoc::on_launch("Launch Printer", |_| {
println!("Rocket is about to launch! Exciting! Here we go...");
}))
.attach(AdHoc::on_request("Put Rewriter", |req, _| {
req.set_method(Method::Put);
}));
```