Calling Jason.decode!/2 in config/config.exs

I have a scenario where developers can configure the endpoint using environment variables. Environment variables are also used in deployments. So in file config/config.exs, I have the following code:

force_ssl_config =
  if System.get_env("FORCE_SSL", "") == "" do
      force_ssl: [
        hsts: true,
          "#{System.get_env("PHX_HOST", "localhost")}:#{System.get_env("URL_PORT", "4000")}",
        cipher_suite: :strong,
        rewrite_on: [:x_forwarded_proto],
          |> System.get_env(~s(["localhost"]))
          # I can't call Jason.decode!/2 here
          |> Jason.decode!()

config :my_app,
         url: [host: "localhost"],
         render_errors: [
           view: MyAppWeb.ErrorView,
           accepts: ~w(html json),
           layout: false
         pubsub_server: MyApp.PubSub,
         live_view: [signing_salt: "salt-value"]
       ] ++ force_ssl_config

Calling Jason.decode!/2 works in config/runtime.exs but not in config/config.exs while force_ssl is a compile time config.

I’m aware of the {module], function, args} setting of the exclude key, but that will require doing decoding json on every request.

So here is what I need help/clarification with:

  • Is there a way to decode json in config/config.exs?

  • If not, can I use the {module, function, args} config without decoding json on every request?

  • Is decoding json on every request even a bad idea (I seem to think so, but I’m not sure)?

  • Any suggestion on how force_ssl can be configured using environment variables?

why do you think its bad to do Jason.decode on every request ? doesn’t that happen for every request anyways, its a pretty standard operation in web service with low overhead. Also with elixir/phoenix each request is independent so comparatively to other languages/framework this will should be negligible IMO

1 Like

You might also give up the use of JSON and just use a simple comma-separated list (“host1,host2,host3”) which you can split with String.split/3. This way you can still use your compile config.

That works perfectly. Thanks.