"Internal" Redirection?

48 views
Skip to first unread message

Kevin Montuori

unread,
Mar 25, 2015, 3:50:15 PM3/25/15
to phoeni...@googlegroups.com
Hi all --

I seem to be stuck with something: basically I'd like to pipeline an incoming request through multiple controllers.  Let's say I have a controller function InitialController.start that an inbound request is routed to.  It does some work (and maybe modififies conn and params) and then forwards those arguments off to FinalizeControler.end that manages rendering.  I'd like end/2 to not know anything at all about start/2.

(In Perl's Catalyst this is an "internal redirect.")

Is this possible?  If so, can you point me towards documentation? 

Thanks!
k.

Chris McCord

unread,
Mar 25, 2015, 3:56:35 PM3/25/15
to phoeni...@googlegroups.com
You’ve just described the `plug` concept at its core. So instead of multiple controllers, you would define plug modules that operation on the connection on its way to the (single) controller:

# router
pipeline :browser do
  plug MyPlug1
  plug MyPlug2
  plug MyPlug3
  …
end

scope “/“, MyApp do
  pipe_through :browser
  get “/“, MyController, :show
end

# my_plug1.ex
defmodule MyApp.MyPlug1 do
  def init(opts), do: opts

  def call(conn, _opts) do
    # some work for step 1
    conn # return the updated conn 
  end
end

# my_plug2.ex
defmodule MyApp.MyPlug2 do
  def init(opts), do: opts

  def call(conn, _opts) do
    # some work for step 2
    conn # return the updated conn 
  end
end

# my_plug3.ex
defmodule MyApp.MyPlug1 do
  def init(opts), do: opts

  def call(conn, _opts) do
    # some work for step 3
    conn # return the updated conn 
  end
end

# my_controller.ex
defmodule MyController do
  …
  def show(conn, params) do
    # conn contains wahtever transformations you applied, but the controller is blissfully unaware of the plugs it travelled through
  end
end



Is that what you have in mind?

Chris

--
You received this message because you are subscribed to the Google Groups "phoenix-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to phoenix-talk...@googlegroups.com.
To post to this group, send email to phoeni...@googlegroups.com.
Visit this group at http://groups.google.com/group/phoenix-talk.
To view this discussion on the web visit https://groups.google.com/d/msgid/phoenix-talk/7f874475-90a9-49ff-a948-5f3963c43c96%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Kevin Montuori

unread,
Mar 25, 2015, 4:53:19 PM3/25/15
to phoeni...@googlegroups.com
>>>>> "cm" == Chris McCord <ch...@chrismccord.com> writes:

cm> You’ve just described the `plug` concept at its core. So instead
cm> of multiple controllers, you would define plug modules that
cm> operation on the connection on its way to the (single)
cm> controller [...]

cm> Is that what you have in mind?

I think what I'm looking to do is almost the opposite of all that, but I
might be misunderstanding. Plugs seem to provide standardized
processing pre-controller function and then the controller adds its
unique work at the end of the pipeline. I'd like to do the unique work
first and have the end of the request cycle managed uniformly.

More concretely, if I have the router fragment

get "/", PageController, :index
get "/baz", FancyController, :baz
get "/quux", OtherController, :quux

I'd like to have FancyController.baz and OtherController.quux do what
they do (which isn't the same thing) and as the last statement in the
function call

PageController.index(conn, params)

and have PageController.index run and PageView manage the view, not
FancyView or OtherView (in fact, I'd like not to have FancyView or
OtherView at all but understand that the placeholders might be
necessary).

An external redirect would accomplish this -- with added latency -- but
the roundtrip to the browser adds no functionality when /baz and /quux
are idempotent.

Thanks for your quick response!

k.

--
Kevin Montuori
mont...@gmail.com

Chris McCord

unread,
Mar 25, 2015, 6:41:18 PM3/25/15
to phoeni...@googlegroups.com
I can’t really see the use-case for this since you’ve already sent the response on the first controller. If for some reason, you hadn’t sent the response and really wanted to do this, realize controllers are just plugs so you could write a tiny function that invokes the controller action, and just plug the actions as needed
> --
> You received this message because you are subscribed to the Google Groups "phoenix-talk" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to phoenix-talk...@googlegroups.com.
> To post to this group, send email to phoeni...@googlegroups.com.
> Visit this group at http://groups.google.com/group/phoenix-talk.
> To view this discussion on the web visit https://groups.google.com/d/msgid/phoenix-talk/m1fv8shk91.fsf%40bapi.us.
Reply all
Reply to author
Forward
0 new messages