You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Elixir中使用Application与Plug.Router实现端口监听

解决Plug应用未监听端口的问题

问题场景

现有以下代码:

Application 文件 (lib/my_api.ex)

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

路由文件 (lib/my_api/router.ex)

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

运行iex -S mix后,应用未监听端口,执行curl请求时出现错误:

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

解决方案

要让应用监听端口并响应请求,需要完成以下步骤:

1. 添加Plug.Cowboy依赖

Plug本身仅提供路由能力,需要Cowboy作为HTTP服务器实现端口监听。修改mix.exs的依赖列表:

defp deps do
  [
    {:plug_cowboy, "~> 2.0"},
    {:jason, "~> 1.0"} # 确保已添加,用于JSON编码
  ]
end

执行mix deps.get安装依赖。

2. 修改Application启动逻辑

直接将Router加入Supervisor的子进程列表不会启动HTTP服务,需要通过Plug.Cowboy.child_spec配置并启动服务器:

defmodule MyApi do
  use Application

  def start(_type, _args) do
    children = [
      # 配置Cowboy服务器,指定协议、路由模块和监听端口
      Plug.Cowboy.child_spec(
        scheme: :http,
        plug: MyApi.Router,
        options: [port: 4000]
      )
    ]

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

3. 定义MyApi.Item模块

路由中使用了%MyApi.Item{}结构体,但当前不存在该模块,需要创建lib/my_api/item.ex:

defmodule MyApi.Item do
  defstruct [:id, :name, :description]
end

4. 测试运行

重新启动应用:

iex -S mix

此时应用会监听4000端口,执行curl请求即可得到响应:

curl http://localhost:4000/api/items

返回结果:

[{"id":1,"name":"Item 1","description":"Description for Item 1"},{"id":2,"name":"Item 2","description":"Description for Item 2"}]

内容的提问来源于stack exchange,提问作者Alexander Mills

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 18:29:50