iT邦幫忙

2023 iThome 鐵人賽

DAY 20
0
Software Development

Rust Web API 從零開始系列 第 20

Day20 - 使用reqwest串接寄信服務

  • 分享至 

  • xImage
  •  

接下來要進一步完善訂閱的功能,當使用者送出訂閱資料時,希望能夠寄送認證信以確認訂閱是有效的,我選擇使用smtp2go的第三方服務來寄送通知信。

Reqwest

在rust要呼叫外部的API可以使用reqwest這個套件。

cargo add reqwest

我們先看一下它的簡單範例

let body = reqwest::get("https://www.rust-lang.org")
    .await?
    .text()
    .await?;

reqwest支援非同步呼叫,並且只要簡單的使用get就可以取得需要的資料。但在應用程式中呼叫第三方API應該要考慮連線數量的問題,官方建議使用client來處裡,我們可以建立一個client並且重複使用,client內部會建立連線池來控管對外API的連線。此外client內部已經自動以Arc實做以利重用,在rust中以Arc包裝的資料就像C#中的參考一樣,在複製的時候只是增加引用計數而不是真的複製一個物件。

EmailClient

為了方便使用,我們將reqwest的client用自定義的結構包起來,並且建立一個建構式:

#[derive(Debug, Clone)]
pub struct EmailClient {
    http_client: Client,
    base_url: Url,
    sender: SubscriberEmail,
    api_key: Secret<String>,
}

impl EmailClient {
    pub fn new(
        base_url: String,
        sender: SubscriberEmail,
        api_key: Secret<String>,
        timeout: std::time::Duration,
    ) -> Self {
        let http_client = Client::builder().timeout(timeout).build().unwrap();

        Self {
            http_client,
            base_url: base_url.parse().unwrap(),
            sender,
            api_key,
        }
    }
}

其中的base_url的型別是透過url這個套件提供,能夠方便的進行網址的解析與組合。接下來就是設定一個簡單的寄信方法,這邊就不贅述了。

單元測試

對於reqwest client的測試,我們需要使用tokio提供對非同步方法的測試,並且透過MockServer來模擬服務接收到的訊息,首先安裝wiremock:

cargo add --dev wiremock

wiremock提供了一系列的組件來協助進行測試物件的替換。--dev安裝的套件只會在測試時使用,release模式編譯的時候會被忽略。

    #[tokio::test]
    async fn send_email_fires_a_request_to_base_url() {
        // Arrange
        let mock_server = MockServer::start().await;
        let token = api_key();
        let email_client = email_client(mock_server.uri(), token.clone());

        Mock::given(method("POST"))
            .and(header("Content-Type", "application/json"))
            .and(path("/v3/email/send"))
            .and(SendEmailBodyMatcher)
            .respond_with(ResponseTemplate::new(200))
            .expect(1)
            .mount(&mock_server)
            .await;

        // Act
        let outcome = email_client
            .send_email(&email(), &subject(), &content())
            .await;

        // Assert
        assert_ok!(outcome);
    }

使用上就是一般測試的寫法,啟動MockServer並且設定收到訊息時的回應以及預計收到的次數就可以了。


上一篇
Day19 - 建立自動化流程
下一篇
Day21 - 整合認證信寄送
系列文
Rust Web API 從零開始30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
Hell Kiki
iT邦新手 4 級 ‧ 2023-09-20 10:43:44

提醒一下:*收先安裝wiremock,應該是首先?

marvinhsu iT邦新手 4 級 ‧ 2023-09-20 14:16:00 檢舉

感謝提醒~

我要留言

立即登入留言