###### 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); })); ```