在Rust库中处理API密钥的最惯用的方法是什么?

Ste*_*eve 2 binding idiomatic rust

我正在为一个API编写Rust绑定,它接受两个API密钥.有很多方法可以实现这一目标.我特别不想给用户带来负担

myapi::requestThing(firstApiKey, SecondApiKey,...)
Run Code Online (Sandbox Code Playgroud)

我想让用户只传入一次API密钥并记住它.问题是我试图在功能上这样做,并将所有内容塞进结构中似乎也不是最好的方法.

She*_*ter 5

你绝对不希望有某种神奇存储的全局配置.这将阻止多个用户在同一进程中同时使用API​​.

我将为API端点构建一个构建器.这可以为API URL提供默认值,也可以从环境变量中获取API密钥.您还可以通过编程方式覆盖URL或键.

use std::collections::HashMap;

struct ApiEndpoint {
    url: String,
    api_key_1: String,
    api_key_2: String,
}

impl ApiEndpoint {
    fn add_money_to_account(&self, cents: u64) {
        println!("Adding {} cents. Making a request to {} ({}, {})", cents, self.url, self.api_key_1, self.api_key_2);
    }
}

struct ApiBuilder {
    url: Option<String>,
    api_key_1: Option<String>,
    api_key_2: Option<String>,
}

impl ApiBuilder {
    fn new() -> ApiBuilder {
        ApiBuilder {
            url: None,
            api_key_1: None,
            api_key_2: None,
        }
    }

    fn url(mut self, url: &str) -> ApiBuilder {
        self.url = Some(url.into());
        self
    }

    fn api_key_1(mut self, api_key_1: &str) -> ApiBuilder {
        self.api_key_1 = Some(api_key_1.into());
        self
    }

    fn api_key_2(mut self, api_key_2: &str) -> ApiBuilder {
        self.api_key_2 = Some(api_key_2.into());
        self
    }

    fn build(self) -> ApiEndpoint {
        let mut env_vars: HashMap<_, _> = std::env::vars().collect();

        ApiEndpoint {
            url: self.url.unwrap_or_else(|| "http://example.com/default".into()),
            api_key_1: self.api_key_1.or_else(|| env_vars.remove("MYLIB_ENV_VAR_1")).unwrap(),
            api_key_2: self.api_key_2.or_else(|| env_vars.remove("MYLIB_ENV_VAR_2")).unwrap(),
        }
    }
}

fn main() {
    let endpoint =
        ApiBuilder::new()
        .url("https://test.example.com")
        .api_key_1("SEEKRET")
        .api_key_2("PASSWORD")
        .build();

    endpoint.add_money_to_account(500);
}
Run Code Online (Sandbox Code Playgroud)

将所有东西塞进结构中似乎也不是最好的方法

我不明白为什么不.