Restricting route forward to only POST requests? Or only certain paths?

I’m working on a custom plug to handle some signin logic for a Phoenix app. Knowing that Phoenix is built on plugs, I thought it might be nice to have this plug handle everything related to this particular request since it felt somewhat arbitrary and redundant to send the request to a controller. In my router I’ve tried a couple things:

scope "/some/path" do
  pipe_through :api
  forward "/", MyApp.CustomPlug

And the unscoped “naked” version of just doing this:

forward "/some/path", MyApp.CustomPlug

Those DO work, but the forward macro will forward EVERYTHING to the plug – GET’s, POST’s, as well as any deeper routes built off of the given one, e.g. /some/path/and/this/is/not/what/i/expected

I like the interface of just being to tie the plug to one route and let it handle everything, but is this misunderstanding how the plug should be used? (I may package this plug separately for use with other apps). If this is a legitimate way to use the plug, how would I restrict it to only respond to POST request, and how would I tell it to ignore any other paths other than the base path?

Of course, I put the plug in a pipeline and handle everything there, but it seems a bit redundant to rely on a pipeline for this. What might be a cleaner way to accomplish this?


You’re close! Just replace forward with

Hmmm, that’s not quite what I’m going for: post only works when it’s inside a scope block (that’s what I meant by “naked” and “unscoped”). forward seems to work anywhere inside your Phoenix router module, even outside a scope block.

Also, if you are just using a plug outside of any pipeline and without ever resolving to a controller, is there a trick to skipping any requests that don’t have application/json? Or would it just return the unaltered conn struct?

You can define a scope at the root level with scope "/" do:...

scope "/" do
  pipe_through :api
  post "/some/path", MyApp.CustomPlug
1 Like