我需要配置OAuth协议,这样做的逻辑位置是在/config/dev.exs
之内,是吗?
在上方,我配置了Endpoint
。因此,在我的应用中,我可以编写Project.Endpoint.static_url()
并获取例如。 http://localhost:4000
。
在配置中获取此值的DRY方法是什么?
config :project, Project.Endpoint,
http: [port: 4000],
url: [scheme: "http", host: "localhost", port: 4000]
config :project, authentication: [
client_id: System.get_env("CLIENT_ID"),
client_secret: System.get_env("CLIENT_SECRET"),
site: "https://example.com",
authorize_url: "/connexion/oauth2/authorize",
redirect_uri: "http://localhost:4000/oauth/callback"
# This version fails: Project.Endpoint.static_url/0 is undefined (module Project.Endpoint is not available)
# redirect_uri: "#{Project.Endpoint.static_url()}/oauth/callback"
]
谢谢
答案 0 :(得分:1)
首先,您应该知道Elixir将在编译时解析配置文件,这意味着System.get_env
将在编译应用程序时进行评估。在已编译的代码中,值将是固定的。
Elixir团队正在努力简化此过程,但是目前建议的解决方法是将环境变量的读取推迟到应用程序启动之前。
通常,这可以在应用程序模块中通过调用Application.put_env/3-4
并放入从System.get_env
读取的值来启动子级之前完成。
诸如Ecto之类的某些库还提供init
回调,使您可以进入引导过程进行动态配置。参见https://hexdocs.pm/ecto/Ecto.Repo.html#module-urls
这也将是摆脱重复的地方。毕竟,配置只是Elixir代码,您可以根据需要简单地基于其他值设置值:
defmodule Project.Application do
use Application
def start(_type, _args) do
Application.put_env :project, authentication: [
redirect_uri: "#{Project.Endpoint.static_url()}/oauth/callback",
...
]
children = [
Project.Repo,
ProjectWeb.Endpoint,
...
]
opts = [strategy: :one_for_one, name: Project.Supervisor]
Supervisor.start_link(children, opts)
end
end
您还可以同时对配置文件和Application.put_env
进行混合匹配,但是您需要自己合并这些值。