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