博客搭建-创建文章接口

创建时间.png 2025-11-26
标签.png tool
阅读量.png 29

前言

上一节我们搭建好了一个最简单的 express 服务,本节,我们将在这个基础上开发出完整的文章接口。

整个过程会从 存储、接口实现、路由 等几个方面展开来讲

数据存储

数据存储我们使用 MongoDB,nodejs 链接 MongoDB 需要使用 mongoose。

mongoose 是一个用于 Node.js 的 MongoDB ODM(对象数据建模)库,帮助开发者更方便地操作 MongoDB 数据库。其核心概念包括:

  1. Schema(模式):定义文档的结构和数据类型,类似数据库表的结构声明,用于约束集合中文档的内容。

  2. Model(模型):基于 Schema 创建的构造函数,代表数据库中的集合,可以用来对数据进行增删查改等操作。

  3. Document(文档实例):通过 Model 新建或查询获得的对象实例,代表数据库中的一条记录,拥有定义好的属性和方法。

  4. 连接(Connection):mongoose 负责与 MongoDB 数据库建立和维护连接,可监听连接状态变化。

通过这些核心概念,mongoose 实现了对 MongoDB 更高级、面向对象的操作方式,并支持数据校验、中间件、钩子等功能,大大提升了开发效率。

mongoose 核心概念

// 1. 引入 mongoose
const mongoose = require('mongoose');

// 2. 连接 MongoDB 数据库
mongoose.connect('mongodb://localhost:27017/article_demo', {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});

// 3. 监听连接状态
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB 连接错误:'));
db.once('open', () => {
  console.log('MongoDB 已连接');
});

// 4. 定义 Schema
const ArticleSchema = new mongoose.Schema({
  title: { type: String, required: true },
  content: String,
  author: String,
  createdAt: { type: Date, default: Date.now },
});

// 5. 给 Schema 添加实例方法
ArticleSchema.methods.brief = function () {
  return {
    title: this.title,
    author: this.author,
    createdAt: this.createdAt,
  };
};

// 6. 创建 Model
const Article = mongoose.model('Article', ArticleSchema);

// 7. 使用 Model 创建实例并保存
async function createArticle() {
  const article = new Article({
    title: '第一篇文章',
    content: '这是文章内容。',
    author: '张三',
  });
  await article.save();
  console.log('保存成功:', article.brief());
}

// 8. 查询列表
async function listArticles() {
  const articles = await Article.find().sort({ createdAt: -1 });
  console.log('文章列表:', articles.map(a => a.brief()));
}

// 9. 调用函数示例
createArticle().then(() => listArticles());

链接数据库

先安装 mongoose

npm i mongoose

然后可以在 入口 app.js 引入 mongoose,然后链接 MongoDB

// src/index.js
const mongoose = require('mongoose')

// 链接 mongoDB
// mongodb: 链接 schema
// localhost:27017 mongodb 地址和端口,本地用 localhost:27017
// blog 是数据仓库的名称
mongoose.connect('mongodb://localhost:27017/blog', {
  useNewUrlParser: true,
  useUnifiedTopology: true,
}).then(() => {
    console.log('MongoDB 链接成功')
});

设置文章存储的数据结构 Schema

在 service 下面创建文件结构 models/article.jsmodels 目录用来存放所有的数据 schema。

// models/article.js
const mongoose = require('mongoose')

// 定义文章的数据结构
const articleSchema = new mongoose.Schema({
  title: {
    type: String,
    required: true,
    trim: true,
  },
  // 这里是转化后的 html 内容,方便渲染,非必须
  content: {
    type: String,
  },
  // 这里是md内容,保存原始的 md
  mdContent: {
    type: String,
    required: true,
  },
  author: {
    type: String,
    trim: true,
  },
  url: {
    type: String,
    trim: true
  },
  keywords: {
    type: array,
    trim: true
  },
  description: {
    type: String,
    trim: true
  },
  tags: {
    type: Array,
  }
})

// 创建 model 实例
const Article = mongoose.model('Article', articleSchema)

// 导出 model
module.exports = Article

接口实现

在实现接口之前,我们先来熟悉 mongoose model 上的几个方法

mongoose model 上的几个方法

// 1. find
// 用于查找符合条件的文章。例如:查找所有作者为"张三"的文章
Article.find({ author: '张三' }).then(articles => {
  console.log(articles)
})

// 2. countDocuments
// 用于统计符合条件的文章数量。例如:统计包含某标签的文章数量
Article.countDocuments({ tags: '技术' }).then(count => {
  console.log(count)
})

// 3. create
// 用于创建新文章。例如:
Article.create({
  title: '新文章标题',
  mdContent: '# 标题',
  author: '李四'
}).then(doc => {
  console.log(doc)
})

// 4. update(推荐使用 updateOne or updateMany)
// 用于更新文章内容。例如:把指定文章的标题修改掉
Article.updateOne(
  { _id: '文章的ID' },
  { $set: { title: '新的标题' } }
).then(result => {
  console.log(result)
})

之后,我们开始接口实现,创建文件 controller/article.js

const articleModel = require('../models/article')

const articleController = {
    getArticleList(req, res)  {
    const page = parseInt(req.query.page, 10) || 1;
    const size = parseInt(req.query.size, 10) || 10;
    const skip = (page - 1) * size;

    // 总数量
    const countPromise = articleModel.countDocuments({});
    // 查询一页
    // skip 用于跳过前面指定数量的文档,常用于分页功能。例如:skip(10) 会跳过前10条数据,从第11条开始查询。
    // limit 用于限制返回的文档数量。例如:limit(5) 只返回5条数据。
    // 在分页查询中,通常配合 skip 和 limit,来实现第 N 页的数据获取。
    const listPromise = articleModel.find({}).skip(skip).limit(size);
    Promise.all([countPromise, listPromise])
      .then(([total, data]) => {
        res.json({
          code: 0,
          msg: 'ok',
          data: {
            list: data,
            total,
            page,
            size
          }
        });
      })
      .catch(err => {
        res.status(500).json({ code: 1, msg: '文章列表查询失败', error: err.message });
      });
    }
    // 其余的请看代码
}

创建路由

新建文件 routes/api.js,接口相关的路由都写在这个目录里

const express = require('express');
const router = express.Router();

// 引入 文章接口实现
const articleController = require('../controller/article');

// 获取文章列表
router.get('/articles', articleController.getArticleList);

// 这里可以继续添加其它接口,比如新增、修改、删除等
// 例如:
// router.post('/articles', articleController.createArticle);
// router.put('/articles/:id', articleController.updateArticle);
// router.delete('/articles/:id', articleController.deleteArticle);

module.exports = router;

再在 app.js 种引入 routes/api.js

const apiRouter = require('./routes/api');
app.use('/api', apiRouter);

至此,我们的整个文章接口已经实现完成。之后使用 pnpm start, 可以通过测试工具,自己测试接口。

原文地址:https://webfem.com/post/website-1,转载请注明出处