How to mimic phoenix routes/controllers syntax with only plug?

It is possible to have a similar Phoenix syntax on Pluig.router with only vanilla Plug?
What I want to achieve is something like

post "/ref", CreateReferralControler, :create do
  ...
  end

where create is a function inside the controller

I thought on creating a few`function plugs but I couldnt understand from documentation if I can declare more than one function plug in the same file to avoid spamming files for the same route (probably no). With plug functions, I could forward requets to specific plugs, but that would force me to create different plugs for each rote behavior or method isnt it? Example, a Plug function for creating, another plug function for deleting, another one for modifying, what would make me create a lot of files to the same route

Plug functions have the following signature
(Plug.Conn.t, Plug.opts) :: Plug.Conn.t
passing the connection to a “main” function plug for the route, and specifying the behavior with an atom in Plug.opts. If the behavior needs additional configuration or to be passed through other different plugs, I could make a Behavior.Plug with Plug.Builder, and forward the connection to that plug.

It’s not the exact DSL you are looking for but there is Plug.Router where you can sorta get that behaviour.

I couldnt find similar to what I want using only Plug.Router, but what do you think about this?

Phoenix controllers are also plugs, where call is called with call(conn, action), which then calls the action function on the module.

Sorry not off the top of my head. You just didn’t mention Plug.Router so wasn’t sure if it would cover what you’re looking for.

I’m am curious, though, what would go in the block of the routes?

now nothing, im still thinking what kind of implementation i’ll follow for all routes, my idea is having the routs just dispatching the logic to plugs/controllers

1 Like

is it a functionality provided by Plug itself or is it manually coded like what I described in here

to close in a lazy way, I was able to do it using match/3

match "/ref", via: :get, to: Referral, init_opts: :teste

or this

get "/ref", to: Referral, init_opts: :test
defmodule MyApp.Controllers.Referral do
  import Plug.Conn


  def init(opts), do: opts

  # Função call que verifica o átomo e responde com "TESTE"
  def call(conn, opts) do
    IO.puts(opts)
    if opts == :test do
      conn
      |> put_resp_content_type("text/plain")
      |> send_resp(200, "TEST")
    else
      conn
      |> put_resp_content_type("text/plain")
      |> send_resp(200, "Hello, World!")
    end
  end
end