Когда я использую вашу конфигурацию, попробуйте получить доступ к ключу в контроллере с помощью:
Application.get_env(:app, App.Notifications)[:notification_api_key]
Я получаю:
{:system, "API_NOTIFICATION_KEY"}
, поэтому Феникс не ищет переменную env. С другой стороны, если я вручную установлю ключ в конфиге, вот так:
config :app, App.Notifications,
notification_api_key: 1234
тогда я получаю 1234
в контроллере. Я прочитал что-то, что говорит, что чтение переменных среды с {:system, "ENV_VAR"}
в какой-то момент будет устаревшим, и я не вижу упоминаний о :system
в документах. Я использую phoenix 1.4.6
.
Согласно этой статье , вы можете определить функцию init/2
в endpoint.ex
, которая будет вызываться во время выполнения - непосредственно перед запуском вашего приложения Phoenix - что означает, что вы можете напрямую просматривать Переменные среды во время выполнения с System.get_env/1
. Функция init/2
описана в документах Phoenix.Endpoint :
Динамическая конфигурация
Для динамического конфигурирования конечной точки, например загрузки данных из
переменные окружения или файлы конфигурации, Phoenix вызывает
Обратный вызов init / 2 в конечной точке, передающий атом: supervisor в качестве первого
аргумент и конфигурация конечной точки в качестве второго.
Вот пример, который я придумал:
def init(:supervisor, config) do
#IO.inspect config, label: "config"
#IO.inspect Application.get_all_env(:app1), label: "all"
Application.put_env(:app1, :notification_api_key,
System.get_env("API_NOTIFICATION_KEY"),
persistent: true
)
{:ok, config}
end
Тогда в моем контроллере:
key = Application.get_env(
:app1, App1.Notifications
)[:notification_api_key]
IO.inspect key, label: "key"
И в окне сервера вижу:
key: 1234
Вы также должны понимать, что установка атрибутов модуля происходит во время компиляции, поэтому эта строка:
@api_notification_key Application.get_env(:app, App.Notifications)[:notification_api_key]
возвращает переменную env для системы, в которой компилируется приложение.
Я также попытался установить атрибут модуля в моем контроллере:
@attr Application.get_env(
:app1, App1.Notifications
)[:notification_api_key]
и init/2
определены в endpoint.ex, как указано выше, и в моем контроллере @attr было равно нулю - как и ожидалось. Это потому, что во время компиляции init/2
еще не был вызван, поэтому значение для :notification_api_key
не было установлено.
Мне кажется, что неправильно звонить Application.put_env()
в init/2
:
def init(:supervisor, config) do
Application.put_env(:app1, :notification_api_key,
System.get_env("API_NOTIFICATION_KEY"),
persistent: true
)
{:ok, config}
end
Я думаю, что должен что-то делать с config
. Вот еще один пример:
def init(:supervisor, config) do
IO.inspect config, label: "config"
key = System.get_env("API_NOTIFICATION_KEY")
new_config = Keyword.put_new(config, :notification_api_key, key)
IO.inspect new_config, label: "inside init/2: new_config"
{:ok, new_config}
end
Тогда в моем контроллере:
IO.inspect(
App1Web.Endpoint.config(:notification_api_key, :not_set),
label: "config"
)
В моем окне сервера я вижу:
config: "1234"
так что тоже работает.