20250730-elixir-phx-blog-api

Table of Contents

📦 1. 创建项目(无前端资源)

mix phx.new blog_api --database mysql --no-html --no-assets --no-dashboard
  • `–no-html`:不生成HTML视图
  • `–no-assets`:不生成前端资源(CSS/JS)
  • `–no-dashboard`:不生成LiveDashboard

⚙️ 2. 配置数据库

修改 `config/dev.exs`:

config :blog_api, BlogApi.Repo,
  username: "your_mysql_user",
  password: "your_mysql_password",
  database: "blog_api_dev",
  hostname: "localhost",
  port: 3306,
  show_sensitive_data_on_connection_error: true,
  pool_size: 10

🧩 3. 安装依赖并初始化

cd blog_api
mix deps.get
mix ecto.create
mix ecto.migrate

🧱 4. 生成核心资源

# 用户资源
mix phx.gen.json Accounts User users username:string password_hash:string

# 文章资源
mix phx.gen.json Content Article articles title:string content:text user_id:references:users

# 评论资源
mix phx.gen.json Content Comment comments content:text article_id:references:articles user_id:references:users

📡 5. 路由配置 (`lib/blog_api_web/router.ex`)

scope "/api", BlogApiWeb do
  pipe_through :api

  resources "/users", UserController, except: [:new, :edit]
  resources "/articles", ArticleController, except: [:new, :edit]
  resources "/comments", CommentController, except: [:new, :edit]
end

🔐 6. 密码安全处理 (`lib/blog_api/accounts/user.ex`)

defmodule BlogApi.Accounts.User do
  use Ecto.Schema
  import Ecto.Changeset

  schema "users" do
    field :username, :string
    field :password_hash, :string
    field :password, :string, virtual: true

    has_many :articles, BlogApi.Content.Article
    has_many :comments, BlogApi.Content.Comment

    timestamps()
  end

  def changeset(user, attrs) do
    user
    |> cast(attrs, [:username, :password])
    |> validate_required([:username, :password])
    |> unique_constraint(:username)
    |> put_password_hash()
  end

  defp put_password_hash(%Ecto.Changeset{valid?: true, changes: %{password: password}} = changeset) do
    change(changeset, password_hash: Bcrypt.hash_pwd_salt(password))
  end
  defp put_password_hash(changeset), do: changeset
end

6.1 别忘了增加`bcrypt`依赖

  • mix.exs
{:bcrypt_elixir, "~> 3.0.1"}

🚀 7. 启动服务器

mix phx.server

默认端口:`http://localhost:4000`

📡 API 测试示例

# 创建用户
curl -X POST http://localhost:4000/api/users \
  -H "Content-Type: application/json" \
  -d '{"user": {"username": "test", "password": "secret"}}'

# 创建文章
curl -X POST http://localhost:4000/api/articles \
  -H "Content-Type: application/json" \
  -d '{"article": {"title": "Phoenix API", "content": "Building JSON APIs", "user_id": 1}}'

⚙️ 项目结构精简说明

blog_api/
├── lib/
│   ├── blog_api/
│   │   ├── accounts/     # 用户领域
│   │   ├── content/      # 文章和评论领域
│   ├── blog_api_web/
│   │   ├── controllers/  # 纯JSON控制器
│   │   ├── views/        # JSON视图
└── config/
    └── dev.exs           # MySQL配置

💡 关键优化:

  1. 使用 `–no-html –no-assets` 彻底移除前端依赖
  2. 密码通过 `bcrypt_elixir` 加密存储
  3. 所有API返回标准JSON格式
  4. 精简的路由配置只暴露必要的REST端点

Date: 2025-07-30 Wed 17:31