在 Elixir config 中使用 ENV 的一點技巧

看到了 Erlang Solution 的這篇文章,想到了這個話題。這篇文章雖然內容不多,但還是挺有用的。文中提到的編譯時和運行時的區別,也是剛學 Elixir 搞不太清的問題。

而 Elixir 的 config 也并不是簡單的啟動前執行的代碼,特別是在部署時。

有時我們可能會想在 config 里使用 ENV,比如:

config :my_app, api_key: System.get_env("API_KEY")

但直接這樣寫到 config 中是不行的。在部署時,比如通過 distillery 運行 mix release ,config 就會變成 sys.config,System.get_env("API_KEY") 已經被計算了,等運行的時候就不能動態得到 ENV 的實際值了。

有種做法就是像上邊那篇文章中最后提到的方式,把 ENV 的獲取邏輯放到函數里去做,這樣就變成了運行時才會執行了:

# config.exs
config :my_app, api_key: {:env, "API_KEY"}

# my_app.ex
def api_key do
  get_env(Application.get_env(:my_app, :api_key))
end

def get_env({:env, key}), do: System.get_env(key)

Phoenix 的 config 支持從 ENV 中獲取 port 就是這樣處理的:

# https://github.com/phoenixframework/phoenix/blob/996a83a27d8ccdc7e0e3bdda9c21d537b19b2002/installer/templates/new/config/prod.exs#L15
config :<%= app_name %>, <%= app_module %>.Endpoint,
  http: [:inet6, port: {:system, "PORT"}]
 
 # https://github.com/phoenixframework/phoenix/blob/2295ba7440221871b64c9535dec404c7d53589eb/lib/phoenix/endpoint/handler.ex#L57
 defp to_port({:system, env_var}), do: to_port(System.get_env(env_var))
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容