How to do Plug pipelines in Elixir?












0















Background



I have an app that is a webserver with cowboy and uses Plugs. Since this app was inherited, using Phoenix is out of the question unless we remake the entire thing, which is not happening.



My objective is to instead of having everything inside one huge file, to have several plugs and connect them via pipelines.



Code



Let’s assume I have a main router Plug, that looks like this:



defmodule MyApp.Web.Router do
use Plug.Router

plug(:match)

forward "/check", to: MyApp.Route.Check
forward "/dispatch", to: MyApp.Plug.Dispatch
end


So here I have 2 things. A Route for the endpoint /check, which looks like this:



defmodule MyApp.Route.Check do
use Plug.Router

plug(:dispatch)

get "/", do: send_resp(conn, 200, "ok")
end


And a Plug pipeline for /dispatch that looks like this:



defmodule MyApp.Plug.Dispatch do
use Plug.Builder

plug(Plug.Parsers, parsers: [:urlencoded]) #parses parameters
plug(MyApp.Plug.Metrics) #exposes /metrics path
plug(Cipher.ValidatePlug) #typical URL validation
plug(MyApp.Route.Dispatch) #forwards to dispatch Route
end


This pipeline parses the parameters, notifies a metrics service, validates the request and then sends it to the proper Router, which looks like this:



defmodule MyApp.Route.Dispatch do
use Plug.Router

plug(:dispatch)

get "/", do: send_resp(conn, 200, "Info dispatched")
end


Problem



The problem here is that nothing works. Quite literally if I launch the application and try to access even the dummest endpoint ( /check ) the code blows with errors:



17:44:03.330 [error] #PID<0.402.0> running MyApp.Web.Router (connection #PID<0.401.0>, stream id 1) terminated
Server: localhost:4003 (http)
Request: GET /check
** (exit) an exception was raised:
** (Plug.Conn.NotSentError) a response was neither set nor sent from the connection
(plug_cowboy) lib/plug/cowboy/handler.ex:37: Plug.Cowboy.Handler.maybe_send/2
(plug_cowboy) lib/plug/cowboy/handler.ex:13: Plug.Cowboy.Handler.init/2
(...)


I have now spent the entirety of my day reading documentation and this was as far as I got. The app is super simple, it is pretty much the hello world for plugs:



https://elixirschool.com/en/lessons/specifics/plug/



But with MyApp.Web.Router instead of the one they use.



A MWE can be seen here:



https://github.com/Fl4m3Ph03n1x/plug-pipeline-problem



What am I doing wrong?










share|improve this question





























    0















    Background



    I have an app that is a webserver with cowboy and uses Plugs. Since this app was inherited, using Phoenix is out of the question unless we remake the entire thing, which is not happening.



    My objective is to instead of having everything inside one huge file, to have several plugs and connect them via pipelines.



    Code



    Let’s assume I have a main router Plug, that looks like this:



    defmodule MyApp.Web.Router do
    use Plug.Router

    plug(:match)

    forward "/check", to: MyApp.Route.Check
    forward "/dispatch", to: MyApp.Plug.Dispatch
    end


    So here I have 2 things. A Route for the endpoint /check, which looks like this:



    defmodule MyApp.Route.Check do
    use Plug.Router

    plug(:dispatch)

    get "/", do: send_resp(conn, 200, "ok")
    end


    And a Plug pipeline for /dispatch that looks like this:



    defmodule MyApp.Plug.Dispatch do
    use Plug.Builder

    plug(Plug.Parsers, parsers: [:urlencoded]) #parses parameters
    plug(MyApp.Plug.Metrics) #exposes /metrics path
    plug(Cipher.ValidatePlug) #typical URL validation
    plug(MyApp.Route.Dispatch) #forwards to dispatch Route
    end


    This pipeline parses the parameters, notifies a metrics service, validates the request and then sends it to the proper Router, which looks like this:



    defmodule MyApp.Route.Dispatch do
    use Plug.Router

    plug(:dispatch)

    get "/", do: send_resp(conn, 200, "Info dispatched")
    end


    Problem



    The problem here is that nothing works. Quite literally if I launch the application and try to access even the dummest endpoint ( /check ) the code blows with errors:



    17:44:03.330 [error] #PID<0.402.0> running MyApp.Web.Router (connection #PID<0.401.0>, stream id 1) terminated
    Server: localhost:4003 (http)
    Request: GET /check
    ** (exit) an exception was raised:
    ** (Plug.Conn.NotSentError) a response was neither set nor sent from the connection
    (plug_cowboy) lib/plug/cowboy/handler.ex:37: Plug.Cowboy.Handler.maybe_send/2
    (plug_cowboy) lib/plug/cowboy/handler.ex:13: Plug.Cowboy.Handler.init/2
    (...)


    I have now spent the entirety of my day reading documentation and this was as far as I got. The app is super simple, it is pretty much the hello world for plugs:



    https://elixirschool.com/en/lessons/specifics/plug/



    But with MyApp.Web.Router instead of the one they use.



    A MWE can be seen here:



    https://github.com/Fl4m3Ph03n1x/plug-pipeline-problem



    What am I doing wrong?










    share|improve this question



























      0












      0








      0








      Background



      I have an app that is a webserver with cowboy and uses Plugs. Since this app was inherited, using Phoenix is out of the question unless we remake the entire thing, which is not happening.



      My objective is to instead of having everything inside one huge file, to have several plugs and connect them via pipelines.



      Code



      Let’s assume I have a main router Plug, that looks like this:



      defmodule MyApp.Web.Router do
      use Plug.Router

      plug(:match)

      forward "/check", to: MyApp.Route.Check
      forward "/dispatch", to: MyApp.Plug.Dispatch
      end


      So here I have 2 things. A Route for the endpoint /check, which looks like this:



      defmodule MyApp.Route.Check do
      use Plug.Router

      plug(:dispatch)

      get "/", do: send_resp(conn, 200, "ok")
      end


      And a Plug pipeline for /dispatch that looks like this:



      defmodule MyApp.Plug.Dispatch do
      use Plug.Builder

      plug(Plug.Parsers, parsers: [:urlencoded]) #parses parameters
      plug(MyApp.Plug.Metrics) #exposes /metrics path
      plug(Cipher.ValidatePlug) #typical URL validation
      plug(MyApp.Route.Dispatch) #forwards to dispatch Route
      end


      This pipeline parses the parameters, notifies a metrics service, validates the request and then sends it to the proper Router, which looks like this:



      defmodule MyApp.Route.Dispatch do
      use Plug.Router

      plug(:dispatch)

      get "/", do: send_resp(conn, 200, "Info dispatched")
      end


      Problem



      The problem here is that nothing works. Quite literally if I launch the application and try to access even the dummest endpoint ( /check ) the code blows with errors:



      17:44:03.330 [error] #PID<0.402.0> running MyApp.Web.Router (connection #PID<0.401.0>, stream id 1) terminated
      Server: localhost:4003 (http)
      Request: GET /check
      ** (exit) an exception was raised:
      ** (Plug.Conn.NotSentError) a response was neither set nor sent from the connection
      (plug_cowboy) lib/plug/cowboy/handler.ex:37: Plug.Cowboy.Handler.maybe_send/2
      (plug_cowboy) lib/plug/cowboy/handler.ex:13: Plug.Cowboy.Handler.init/2
      (...)


      I have now spent the entirety of my day reading documentation and this was as far as I got. The app is super simple, it is pretty much the hello world for plugs:



      https://elixirschool.com/en/lessons/specifics/plug/



      But with MyApp.Web.Router instead of the one they use.



      A MWE can be seen here:



      https://github.com/Fl4m3Ph03n1x/plug-pipeline-problem



      What am I doing wrong?










      share|improve this question
















      Background



      I have an app that is a webserver with cowboy and uses Plugs. Since this app was inherited, using Phoenix is out of the question unless we remake the entire thing, which is not happening.



      My objective is to instead of having everything inside one huge file, to have several plugs and connect them via pipelines.



      Code



      Let’s assume I have a main router Plug, that looks like this:



      defmodule MyApp.Web.Router do
      use Plug.Router

      plug(:match)

      forward "/check", to: MyApp.Route.Check
      forward "/dispatch", to: MyApp.Plug.Dispatch
      end


      So here I have 2 things. A Route for the endpoint /check, which looks like this:



      defmodule MyApp.Route.Check do
      use Plug.Router

      plug(:dispatch)

      get "/", do: send_resp(conn, 200, "ok")
      end


      And a Plug pipeline for /dispatch that looks like this:



      defmodule MyApp.Plug.Dispatch do
      use Plug.Builder

      plug(Plug.Parsers, parsers: [:urlencoded]) #parses parameters
      plug(MyApp.Plug.Metrics) #exposes /metrics path
      plug(Cipher.ValidatePlug) #typical URL validation
      plug(MyApp.Route.Dispatch) #forwards to dispatch Route
      end


      This pipeline parses the parameters, notifies a metrics service, validates the request and then sends it to the proper Router, which looks like this:



      defmodule MyApp.Route.Dispatch do
      use Plug.Router

      plug(:dispatch)

      get "/", do: send_resp(conn, 200, "Info dispatched")
      end


      Problem



      The problem here is that nothing works. Quite literally if I launch the application and try to access even the dummest endpoint ( /check ) the code blows with errors:



      17:44:03.330 [error] #PID<0.402.0> running MyApp.Web.Router (connection #PID<0.401.0>, stream id 1) terminated
      Server: localhost:4003 (http)
      Request: GET /check
      ** (exit) an exception was raised:
      ** (Plug.Conn.NotSentError) a response was neither set nor sent from the connection
      (plug_cowboy) lib/plug/cowboy/handler.ex:37: Plug.Cowboy.Handler.maybe_send/2
      (plug_cowboy) lib/plug/cowboy/handler.ex:13: Plug.Cowboy.Handler.init/2
      (...)


      I have now spent the entirety of my day reading documentation and this was as far as I got. The app is super simple, it is pretty much the hello world for plugs:



      https://elixirschool.com/en/lessons/specifics/plug/



      But with MyApp.Web.Router instead of the one they use.



      A MWE can be seen here:



      https://github.com/Fl4m3Ph03n1x/plug-pipeline-problem



      What am I doing wrong?







      elixir plug






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 20 '18 at 11:17







      Flame_Phoenix

















      asked Nov 20 '18 at 8:39









      Flame_PhoenixFlame_Phoenix

      6,0341778162




      6,0341778162
























          1 Answer
          1






          active

          oldest

          votes


















          3














          Route was not matching on Example.Route.Dispatch and Example.Route.Check. To fix that you need to make two changes:



          defmodule Example.Route.Dispatch do
          use Plug.Router

          plug(:dispatch)

          get "/*glob", do: send_resp(conn, 200, "Info dispatched")
          end


          and



          defmodule Example.Route.Check do
          use Plug.Router

          plug :match
          plug :dispatch

          get "/*glob" do
          send_resp(conn, 200, "ok")
          end
          end


          Alternatively, you can do this: https://github.com/Fl4m3Ph03n1x/plug-pipeline-problem/pull/1



          To understand more about why it is not matching you can use Plug.Router.match_path/1 on a "catch all" match.






          share|improve this answer

























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53389081%2fhow-to-do-plug-pipelines-in-elixir%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            3














            Route was not matching on Example.Route.Dispatch and Example.Route.Check. To fix that you need to make two changes:



            defmodule Example.Route.Dispatch do
            use Plug.Router

            plug(:dispatch)

            get "/*glob", do: send_resp(conn, 200, "Info dispatched")
            end


            and



            defmodule Example.Route.Check do
            use Plug.Router

            plug :match
            plug :dispatch

            get "/*glob" do
            send_resp(conn, 200, "ok")
            end
            end


            Alternatively, you can do this: https://github.com/Fl4m3Ph03n1x/plug-pipeline-problem/pull/1



            To understand more about why it is not matching you can use Plug.Router.match_path/1 on a "catch all" match.






            share|improve this answer






























              3














              Route was not matching on Example.Route.Dispatch and Example.Route.Check. To fix that you need to make two changes:



              defmodule Example.Route.Dispatch do
              use Plug.Router

              plug(:dispatch)

              get "/*glob", do: send_resp(conn, 200, "Info dispatched")
              end


              and



              defmodule Example.Route.Check do
              use Plug.Router

              plug :match
              plug :dispatch

              get "/*glob" do
              send_resp(conn, 200, "ok")
              end
              end


              Alternatively, you can do this: https://github.com/Fl4m3Ph03n1x/plug-pipeline-problem/pull/1



              To understand more about why it is not matching you can use Plug.Router.match_path/1 on a "catch all" match.






              share|improve this answer




























                3












                3








                3







                Route was not matching on Example.Route.Dispatch and Example.Route.Check. To fix that you need to make two changes:



                defmodule Example.Route.Dispatch do
                use Plug.Router

                plug(:dispatch)

                get "/*glob", do: send_resp(conn, 200, "Info dispatched")
                end


                and



                defmodule Example.Route.Check do
                use Plug.Router

                plug :match
                plug :dispatch

                get "/*glob" do
                send_resp(conn, 200, "ok")
                end
                end


                Alternatively, you can do this: https://github.com/Fl4m3Ph03n1x/plug-pipeline-problem/pull/1



                To understand more about why it is not matching you can use Plug.Router.match_path/1 on a "catch all" match.






                share|improve this answer















                Route was not matching on Example.Route.Dispatch and Example.Route.Check. To fix that you need to make two changes:



                defmodule Example.Route.Dispatch do
                use Plug.Router

                plug(:dispatch)

                get "/*glob", do: send_resp(conn, 200, "Info dispatched")
                end


                and



                defmodule Example.Route.Check do
                use Plug.Router

                plug :match
                plug :dispatch

                get "/*glob" do
                send_resp(conn, 200, "ok")
                end
                end


                Alternatively, you can do this: https://github.com/Fl4m3Ph03n1x/plug-pipeline-problem/pull/1



                To understand more about why it is not matching you can use Plug.Router.match_path/1 on a "catch all" match.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Nov 20 '18 at 15:44

























                answered Nov 20 '18 at 10:38









                Marcos TapajósMarcos Tapajós

                1915




                1915
































                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53389081%2fhow-to-do-plug-pipelines-in-elixir%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

                    ComboBox Display Member on multiple fields

                    Is it possible to collect Nectar points via Trainline?