iT邦幫忙

2023 iThome 鐵人賽

DAY 9
0
Software Development

Rust Web API 從零開始系列 第 9

Day09 - 應用程式模組

  • 分享至 

  • xImage
  •  

目前lib.rs的內容如下

//// lib.rs
mod handler;

use handler::*;

use axum::Router;
use axum::routing::get;
use serde::Deserialize;

pub async fn run(app: Router) {
    axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
        .serve(app.into_make_service())
        .await
        .unwrap();
}

pub fn build() -> Router {
    let app = Router::new().route("/", get(health_check));
    app
}

我想要進一步把這兩個方法移出lib.rs首先我們建立一個application.rs的檔案,並把這兩個方法移入:

//// application.rs
use axum::Router;
use axum::routing::get;
use crate::handler::health_check;

pub struct Application {
    port: u16,
    router: Router,
}

pub async fn run(app: Router) {
    axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
        .serve(app.into_make_service())
        .await
        .unwrap();
}

pub fn build() -> Router {
    let app = Router::new().route("/", get(health_check));
    app
}

這邊的意圖是將應用程式封裝提供一個一致的界面供進入點使用,應用程式本體會紀錄要監聽的port以及路由設定,我們可以將build方法視為準備整個應用程式,而run則是運行,所以將以上程式碼再改一下:

//// application.rs
use axum::Router;
use axum::routing::get;
use crate::handler::health_check;

pub struct Application {
    port: u16,
    router: Router,
}

impl Application {
    pub async fn build() -> Self {
        let router = Router::new()
            .route("/", get(health_check));

        Ok(Self {
            port: 3000,
            router,
        })
    }

    pub async fn run(self) {
        let addr = std::net::SocketAddr::from(([0, 0, 0, 0], self.port));

        Server::bind(&addr)
            .serve(self.router.into_make_service())
            .await
            .unwrap();
    }
}

rust的一個特色是將資料與應用程式的方法分開來,與C#以類別將資料與方法封裝十分不同。經過上面的重構後,就可以將main.rs調整成以下:

use zero_to_production::*;

#[tokio::main]
async fn main() {
    Application::build().run().await;
}

由使用方來看,這樣的封裝意圖就變得很明顯,先是準備應用程式,並且運行應用程式。這時候再回來看lib.rs:

mod handler;
mod application;

pub use application::*;

這就是昨天提到的組織模組,我們需要將handlerapplication模組加入整個專案套件中,值得注意的是這邊只有公開了application模組,因為對外部而言並不需要知道整個應用程式的運作。

小結

目前的專案結構如下:

.
├── Cargo.lock
├── Cargo.toml
└── src
    ├── application.rs
    ├── handler
    │   ├── health_check.rs
    │   ├── mod.rs
    │   └── subscribe.rs
    ├── lib.rs
    └── main.rs

這個階段的重構到這裡大致完成,可以運行一下測試來確認一切正常,明天要繼續推進這隻API的功能。


上一篇
Day08 - 透過重構了解Rust的模組管理
下一篇
Day10 - 單元測試與Domain Module
系列文
Rust Web API 從零開始30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言