Using conditionally compiled routes with verified routes

I have added a page that is only available in development

defmodule MyWeb.Router do
  use MyWeb, :router

  ...
  
  # Enable LiveDashboard and Swoosh mailbox preview in development
  if Application.compile_env(:tax_comps, :dev_routes) do
    import Phoenix.LiveDashboard.Router

    scope "/dev" do
      pipe_through :browser

      get "/myroute", MyWeb.DevMyRouteController, :blah
      post "/myroute", MyWeb.DevMyRouteController, :blah
    end
  end
end

this renders a form

<.simple_form :let={_form} for={@conn.params["blah_request"]} action={~p"/dev/myroute"} >
  <.input type="textarea" name="stuff" value={@stuff} label="Stuff?"/>
  <:actions>
      <.button name="separate" value="false">Go</.button>
  </:actions>
</.simple_form>

When running mix test --force I am getting

warning: no route path for MyWeb.Router matches "/dev/myroute"

I belive I could use the route helpers but I see this is deprecated, and in my Phoenix 1.17 project these helpers are disabled by default.

What is the recommended way to fix this?

Instead of only making them available in development, make them only available in production.

I don’t want to have these routes available in production, they are routes for developers to test the system.

Oops sorry that was a very unfortunate typo. I meant make them UNavailable in production, ie, they will work in any other env. ie if Mix.env() != :prod, do: # ....

2 Likes

As @sodapopcan mentioned, checking that the env is not prod is a very good solution.

To formulate on why you are getting this warning: this is due the fact that you have defined dev_routes only in dev.exs configuration. The tests are not using dev configuration by default, but its specific one that is test.exs, hence making those routes unavailable in the test environment.

As an alternative to the solution that was provided above, you could add dev_routes and set it to true in your test configuration, however I would always go with the solution that checks that the env is not prod, as it has much smaller footprint and it is times more readable.

As a word of warning, if this warning comes from your application code (as opposed to your tests) then you are most probably doing something wrong, you shouldn’t use environment specific routes in application code, as that would imply that the functionality using it will not work correctly across all environments.

1 Like

You can always use non-verified routes for those, by removing the ~p sigil, especially if they are dev only (so any mistake only affects dev, which you can quickly address).

1 Like

Thanks, that seems like the best solution. For some reason it didn’t even cross my mind that the action could be a string.

This doesn’t seem like a great practice to me. In this case it’s perhaps harmless, but it doesn’t set a good precedent as it means test is inconsistent with dev in non-obvious ways. Perhaps I’m overthinking it :thinking:

1 Like