🎯 第 18 课:实战项目③ —— 用 Express 搭建一个博客 API(支持增删改查)

0 阅读3分钟

太棒了!👏 你已经掌握了 Express 的核心三剑客,现在我们来做一个真正实用的项目:


📌 目标
构建一个简单的 RESTful 博客 API,实现 CRUD 操作(创建、读取、更新、删除文章),数据暂存在内存中。

最终我们将支持以下接口:

方法路径功能
GET/posts获取所有文章列表
GET/posts/:id获取某一篇文章
POST/posts添加一篇新文章
PUT/posts/:id更新某篇文章
DELETE/posts/:id删除某篇文章

📁 项目结构

blog-api/
├── app.js           ← 主程序

我们先不连接数据库,数据保存在内存数组中,便于学习原理。


✅ 第一步:初始化项目

mkdir blog-api
cd blog-api
npm init -y
npm install express

✅ 第二步:编写 app.js

// app.js
const express = require('express');
const app = express();

// 👉 启用中间件
app.use(express.json()); // 解析 JSON 请求体
app.use((req, res, next) => {
  console.log(`${req.method} ${req.path}`);
  next();
});

// 🧠 模拟数据存储(实际项目会用数据库)
let posts = [
  { id: 1, title: '我的第一篇博客', content: 'Hello World!我开始写博客啦~' },
  { id: 2, title: 'Node.js 入门心得', content: '原来后端也可以用 JavaScript 写!' }
];

// 🔢 自动生成 ID 的工具函数
function generateId() {
  return posts.length > 0 ? Math.max(...posts.map(p => p.id)) + 1 : 1;
}

// 🌐 API 路由开始 ----------------------------------

// ✅ GET /posts - 获取所有文章
app.get('/posts', (req, res) => {
  res.json({
    success: true,
    count: posts.length,
    data: posts
  });
});

// ✅ GET /posts/:id - 获取单篇文章
app.get('/posts/:id', (req, res) => {
  const id = parseInt(req.params.id);
  const post = posts.find(p => p.id === id);

  if (!post) {
    return res.status(404).json({
      success: false,
      message: `未找到 ID 为 ${id} 的文章`
    });
  }

  res.json({
    success: true,
    data: post
  });
});

// ✅ POST /posts - 创建新文章
app.post('/posts', (req, res) => {
  const { title, content } = req.body;

  // 简单验证
  if (!title || !content) {
    return res.status(400).json({
      success: false,
      message: '请提供标题和内容'
    });
  }

  // 创建新文章
  const newPost = {
    id: generateId(),
    title,
    content
  };

  posts.push(newPost);

  res.status(201).json({
    success: true,
    message: '文章创建成功',
    data: newPost
  });
});

// ✅ PUT /posts/:id - 更新文章
app.put('/posts/:id', (req, res) => {
  const id = parseInt(req.params.id);
  const post = posts.find((p, index) => {
    if (p.id === id) {
      // 顺便记住索引,方便更新
      req.postIndex = index;
      return true;
    }
    return false;
  });

  if (!post) {
    return res.status(404).json({
      success: false,
      message: `未找到 ID 为 ${id} 的文章`
    });
  }

  const { title, content } = req.body;
  if (!title || !content) {
    return res.status(400).json({
      success: false,
      message: '请提供标题和内容'
    });
  }

  // 更新文章
  posts[req.postIndex] = { id, title, content };

  res.json({
    success: true,
    message: '文章更新成功',
    data: posts[req.postIndex]
  });
});

// ✅ DELETE /posts/:id - 删除文章
app.delete('/posts/:id', (req, res) => {
  const id = parseInt(req.params.id);
  const initialLength = posts.length;
  posts = posts.filter(p => p.id !== id);

  if (posts.length === initialLength) {
    return res.status(404).json({
      success: false,
      message: `未找到 ID 为 ${id} 的文章`
    });
  }

  res.json({
    success: true,
    message: '文章删除成功'
  });
});

// ❌ 处理 404 路由(必须放在最后)
app.use((req, res) => {
  res.status(404).json({
    success: false,
    message: 'API 路径不存在'
  });
});

// 🚀 启动服务器
const PORT = 3000;
app.listen(PORT, () => {
  console.log(`✅ 博客 API 已启动:http://localhost:${PORT}`);
});

🏃‍♂️ 第三步:测试你的 API

方法①:使用浏览器(只适合 GET)


方法②:使用 curl 命令行测试

添加一篇新文章:

curl -X POST http://localhost:3000/posts \
  -H "Content-Type: application/json" \
  -d '{"title":"第三篇","content":"这是通过 API 添加的文章"}'

更新文章:

curl -X PUT http://localhost:3000/posts/1 \
  -H "Content-Type: application/json" \
  -d '{"title":"已修改","content":"内容也被改了"}'

删除文章:

curl -X DELETE http://localhost:3000/posts/1

方法③:推荐使用 Postman 或 Thunder Client(VS Code 插件)

图形化界面,更直观地测试各种请求。


✅ 本课小结一句话:

我们用 Express 快速搭建了一个功能完整的博客 API,实现了标准的 CRUD 操作,返回统一格式的 JSON 数据,这是现代 Web 开发中最常见的服务形态。


📝 学到了什么?

技术点说明
app.use(express.json())自动解析 JSON 请求体
req.params获取路径参数(如 :id
req.body获取 POST 提交的数据
res.status(code).json()返回状态码 + JSON 响应
RESTful 设计使用标准 HTTP 方法对应操作
内存模拟数据快速原型开发的好方法

📬 下一课预告:
第 19 课:package.json 详解 —— 如何管理项目依赖与脚本命令?

我们将学习这个 Node.js 项目的“身份证”文件,理解 dependenciesscripts 等关键字段。