前言

在寫小工具或練習專案時,把設定值直接寫在程式裡通常不會有太大問題。

例如:

1
2
var apiUrl = "https://api.example.com";
var timeout = 30;

但當專案開始部署到不同環境,像是本機、測試機、正式機,這種寫法就很容易變成維護上的麻煩。

這篇整理一下,為什麼我現在會盡量避免把設定值寫死在程式碼裡。

寫死設定值的問題

最常見的問題是:不同環境需要不同設定。

例如:

環境 API URL
local http://localhost:5000
staging https://staging-api.example.com
production https://api.example.com

如果這些設定都寫死在程式裡,每次切換環境都要改程式碼。

這會帶來幾個風險:

  • 容易把測試環境設定部署到正式環境。
  • 每次改設定都需要重新打包。
  • 敏感資訊可能被 commit 到 Git。
  • 其他開發者不容易知道哪些值應該依環境調整。

寫死設定看似方便,但後面常常會把成本還回來。

設定值應該和程式邏輯分開

比較好的方向是:程式只描述邏輯,設定則由外部提供。

例如 API URL、資料庫連線字串、第三方服務金鑰、timeout 秒數,都可以放到設定檔或環境變數。

概念上可以像這樣:

1
2
var apiUrl = configuration["Api:BaseUrl"];
var timeout = configuration.GetValue<int>("Api:Timeout");

程式不需要知道自己跑在哪個環境,只需要讀取目前環境提供的設定。

這樣同一份程式碼,就能在不同環境使用不同設定。

哪些東西適合抽成設定?

我會優先把這幾類值抽出來:

  • API endpoint
  • Database connection string
  • Token、Secret、Password
  • Timeout、Retry 次數
  • Feature flag
  • 檔案路徑或外部服務位置

判斷方式也很簡單:

如果這個值在不同環境可能不同,就不要寫死在程式裡。

如果這個值包含敏感資訊,更不應該放進版本控制。

設定檔也要注意安全

把設定移出程式碼,不代表所有設定檔都可以放心 commit。

像下面這種內容就要特別小心:

1
2
3
4
5
{
"Database": {
"ConnectionString": "Server=prod-db;User Id=admin;Password=secret;"
}
}

如果這種檔案被 commit 到公開 repo,問題就很大了。

常見做法會是:

  • 提供 appsettings.example.json 當範本。
  • 真正含有敏感資訊的設定檔加入 .gitignore
  • 部署時透過 CI/CD 或主機環境變數注入設定。

範本檔可以讓其他人知道需要哪些設定,但不暴露真正的值。

設定名稱也要語意化

設定不只是放在外面就好,命名也要清楚。

例如:

1
2
3
URL1
TIME
KEY

這種命名過一段時間就會讓人困惑。

比較好的命名會像:

1
2
3
4
Api__BaseUrl
Api__TimeoutSeconds
Mail__SenderApiKey
Database__ConnectionString

看到名稱時,就能大概理解用途和所屬模組。

結語

設定值寫死在程式裡,一開始很快,但專案一旦變大,就會變成很難控管的風險。

我的習慣是:

  • 環境會變的值抽出來。
  • 敏感資訊不要 commit。
  • 提供範本設定檔,讓開發者知道要準備什麼。
  • 設定名稱要能看出用途。

這些事情都不是很難,但能讓部署和維護穩很多。