How to generate url in non-web application inside Phoenix umbrella project?


How to use router helpers in an non-web application inside an umbrella project to generate url given that:

  1. Inverting application dependencies is not an option - view tests depends on the schemas from the non-web application
  2. The url generation occurs 3 modules down: Controller -> Orchestration module -> Operation module -> Utility module and passing an pregenerated url from controller all the way down is awkward.
1 Like

Does it have to generate a url, maybe a url can be passed from the phoenix app?

# in phoenix app
url = Routes.some_url(conn, :index)
OtherApp.do_stuff(data, url: url)

Can a closure for url generation be passed into?

# in phoenix app
url_generator = fn other_app_resp ->
  # which might call Routes.some_url(conn, ...)
  # since it captures conn
  generate_url(conn, other_app_resp)
OtherApp.do_stuff(data, url_generator: url_generator)

Or maybe you can point to the Routes module from other app’s config. And have some “dispath” module for two-way communication between them.

@idi527 that will be ugly as hell because url needed 3 invocations down and first two modules are fully unaware of that url.

No, inverting application dependencies will create more problems:

web app should depend on the non-web app

I’d use a configuration to for the main app like config :myapp, route_helpers: MyAppWeb.Router.Helpers, endpoint: MyAppWeb.Endpoint and use those to generate the urls. So you at least don’t have hardcoded coupling. But in the end your main app is still depending on the web layer if you’re not creating an different way to build those urls.

1 Like

I’m not suggesting to invert the dependencies, just point back from the other app to some “dispatch” module in the phoenix app in the config.

Like in Best practice for calling a function in another application without defining a dependency

1 Like

Thanks guys, that may definitely work!