on
[rust] zero2prod 實做紀錄 03 - Health Check
zero2prod是一個webapi專案,書上建議從actix-web這個框架著手。在rust的世界裡有很多的web framework,而actix只是其中一種,身為C#入門的工程師,這點真的很不習慣。.Net的世界裡大家基本上就是follow微軟的腳步,有一個老大哥建議程式要怎麼寫,尤其.Net core發布後大行其道。rust除了actix-web以外也有很多其他框架,不過這邊就不詳談了。
actix_web::main
把cargo專案設置好後,先直接把main.rs的部份換掉,書上用的actix-web是4.0.0版的,在這邊我直接換成4.3.0
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(||{
App::new()
.route("/health_check", web::get().to(health_check))
})
.bind(("127.0.0.1",8080))?
.run()
.await
}
async fn health_check(_req: HttpRequest) -> impl Responder{
HttpResponse::Ok()
}
先從內部往外看,||{}
這個看起來很詭異的東西就是一個lambda表達式,翻譯成C#就是()=>{}
,是一個不接受任何參數的方法,並且回傳App
這個結構的實例。我們可以在App上面設定route,第一個就是範例中給的透過.route()
來設定路由,將health_check綁定成get
。另一種則是透過.service()
// App instance
App::new()
.service(health_check)
// health_check handler
#[get("/")]
async fn health_check(_req: HttpRequest) -> impl Responder{
HttpResponse::Ok()
}
看一下health_check
的回傳是Responder
,在rust中使用的是trait,類似於其他語言中的interface,表示要回傳值需要實作Responder trait。另外一個可以介紹的是用於設定handler的.to()
:
pub fn to<F, Args>(handler: F) -> Route
where
F: Handler<Args>,
Args: FromRequest + 'static,
F::Output: Responder + 'static,
這邊只是想提到rust的生命週期,'static
表示這個變數生命週期在整個應用程式的執行期間,但在這邊其實有細微的不同,可以參考這一篇介紹,簡單來說這邊指的是Args這個型別生命週期在一次request作用內都需要是可用的。
App
instance被用來建構HttpServer
後,後面的方法鏈就可以來建構middelware。
最後看到main被掛上#[actix_web::main]
後就需要回傳Result型別,這是一個enum,在rust以及函數式語言中,都會顯式表達方法會回傳一個結果,或者是執行失敗。因為將方法改為非同步後,就需要考慮例外狀況,而Result
裡面的()
有人稱為unit,表示沒有結果,因為方法內容執行成功後不需要特別回傳結果,所以這邊的回傳值就是Result<()>
。
小結
終於寫完第一篇,總覺的因為對rust不熟,某些認知應該是錯的,就留到以後慢慢改學習改進吧!