Search code examples
elixirelixir-mixplug

How to use Application and Plug.Router to listen on port with Elixir


I have this Application file:

defmodule MyApi do
  use Application

  def start(_type, _args) do
    children = [
      MyApi.Router
    ]

    opts = [strategy: :one_for_one, name: MyApi.Supervisor]
    Supervisor.start_link(children, opts)
  end
end

and then a router file like so:

defmodule MyApi.Router do
  use Plug.Router

  plug :match
  plug :dispatch

  # Dummy data to store items in memory
  @items [
    %MyApi.Item{id: 1, name: "Item 1", description: "Description for Item 1"},
    %MyApi.Item{id: 2, name: "Item 2", description: "Description for Item 2"}
  ]

  # Route to get all items
  get "/api/items" do
    send_resp(conn, 200, Jason.encode!(@items))
  end

  # Handle requests to unknown routes
  match _ do
    send_resp(conn, 404, "Not found")
  end
end

but when I run ies -S mix then project is not listening on a port. I want to curl and hit this route:

bash-3.2$ curl http://localhost:4000/api/items
curl: (7) Failed to connect to localhost port 4000 after 9 ms: Connection refused

anyone know how to listen on a port and engage the router?


Solution

  • Following the Bandit docs:

    1. Add :bandit to your list of deps in mix.exs
    2. In MyApi, change MyApi.Router to {Bandit, plug: MyApi.Router}

    Bandit is the newer pure Elixir web server, Cowboy is the older Erlang one. Both are mentioned in the Plug installation docs.