How to verify routes from multiple routers?

Hi all,

I am working on an application with routers separated by their domain. The application has MyApp.Expenses.Router, MyApp.Inventory.Router etc…

I have written a plug to redirect the traffic to the right router and it works well, however, Phoenix is not recognising routes outside MyAppWeb.Router as verified. When I attempted to list/ quote all the routers in the MyAppWeb.Router.verified_routes Phoenix is overriding them and only recognises the last one.

How do I achieve the verification routes located in different files?

1 Like

From the documentation of Phoenix.VerifiedRoutes:

When the Router module differs from the one passed to use Phoenix.VerifiedRoutes, such as library code, or application code that relies on multiple routers. In such cases, the router module can be provided explicitly to path/3 and url/3.

If you look above, the default global setup works with only a single router:

use Phoenix.VerifiedRoutes,
  router: AppWeb.Router,
  endpoint: AppWeb.Endpoint,
  statics: ~w(images)

This is not really global, but per module / per use call. But I don’t think there’s a way to verify routes of different routers within the same module.

Makes sense, even though by default this option is defined in MyAppWeb, so some structural changes of your phoenix project are in order for this.

I would rather use the path/3 and url/3 option from a helper macro/macros that I could easily define and import in MyAppWeb.

1 Like

I did something similar, and it worked out simplest to forward from one router to the other. Then everything is verified from the context of the parent router, and ~p works as expected.

It could be more prominent but the clearest docs for this are under url:

Forwarded routes are also resolved automatically. For example, imagine you
have a forward path to an admin router in your main router:

  defmodule AppWeb.Router do
    ...
    forward "/admin", AppWeb.AdminRouter
  end

  defmodule AppWeb.AdminRouter do
    ...
    get "/users", AppWeb.Admin.UserController
  end

Forwarded paths in your main application router will be verified as usual,
such as ~p"/admin/users".

3 Likes

Thank you. This solves my problem.

1 Like