# 这是针对 Node.js 后端项目的工具类模块

# 让我们先总结

目录结构:

/project-root
|-- controllers
|   |-- blogs.js
|-- models
|   |-- blog.js
|-- node_modules
|-- requests
|   |-- create_note.rest
|-- utils
|   |-- config.js
|   |-- logger.js
|   |-- middleware.js
|-- .env
|-- .gitignore
|-- app.js
|-- index.js
|-- package-lock.json
|-- package.json

# app.js (核心入口)

这里是应用程序主配置文件
这里发生的事:

  • 初始化 Express 应用
  • 连接 MongoDB 数据库
  • 注册全局中间件 (cors、JSON 解析、请求日志)
  • 挂载博客路由到 /api/blogs 路径
  • 配置错误处理中间件

# index.js (服务启动器)

这里是服务器启动入口
这里发生的事:

  • 创建 HTTP 服务器
  • 监听配置端口
  • 启动时输出运行日志

# models/blog.js (数据层核心)

这里是 Mongoose 数据模型
这里发生的事:

  • 定义博客数据模型 (title、author、url、likes)
  • 配置数据转换逻辑 (隐藏_id 和_v, 暴露 id)
  • 提供数据操作接口

# controllers/blogs.js (业务逻辑层)

这是一个路由控制器
这里发生的事:

  • 处理 /api/blogs 的 GET/POST 请求
  • 调用 Mongoose 模型进行数据库操作
  • 返回 JSON 格式响应

# utils/middleware.js (中间件)

这里发生的事:

  • 配置全局错误处理中间件
  • 配置请求日志中间件
  • 配置响应头中间件
  • 配置响应体中间件
  • 配置请求参数中间件

# utils/logger.js (日志)

这里发生的事:

  • 配置日志输出格式
  • 配置日志输出级别

# utils/config.js (配置)

这里发生的事:

  • 配置数据库连接地址
  • 配置日志输出路径
  • 设置端口

# 最后再开始

以一个初始的博客列表应用的后端代码出发:

const http = require('http')
const express = require('express')
const app = express()
const cors = require('cors')
const mongoose = require('mongoose')
const blogSchema = new mongoose.Schema({
  title: String,
  author: String,
  url: String,
  likes: Number
})
const Blog = mongoose.model('Blog', blogSchema)
const mongoUrl = 'mongodb://localhost/bloglist'
mongoose.connect(mongoUrl)
app.use(cors())
app.use(express.json())
app.get('/api/blogs', (request, response) => {
  Blog
    .find({})
    .then(blogs => {
      response.json(blogs)
    })
})
app.post('/api/blogs', (request, response) => {
  const blog = new Blog(request.body)
  blog
    .save()
    .then(result => {
      response.status(201).json(result)
    })
})
const PORT = 3003
app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`)
})

# blog.js 模型

const mongoose = require('mongoose');
const blogSchema = new mongoose.Schema({
  title: String,
  author: String,
  url: String,
  likes: Number
})
blogSchema.set('toJSON', {
    transform: (document, returnedObject) => {
      returnedObject.id = returnedObject._id.toString()
      delete returnedObject._id
      delete returnedObject.__v
    }
  })
module.exports = mongoose.model('Blog', blogSchema);

# blogs.js 控制器

const blogsRouter = require('express').Router()
const Blog = require('../models/blog')
blogsRouter.get('/', (request, response) => {
    Blog
      .find({})
      .then(blogs => {
        response.json(blogs)
      })
})
blogsRouter.post('/', (request, response) => {
  const blog = new Blog(request.body)
  blog
    .save()
    .then(result => {
      response.status(201).json(result)
    })
})
module.exports = blogsRouter

# app.js 配置

const config = require('./utils/config')
const express = require('express')
const app = express()
const cors = require('cors')
const blogsRouter = require('./controllers/blogs') // 路由器
const middleware = require('./utils/middleware') // 中间件
const logger = require('./utils/logger') // 日志
const mongoose = require('mongoose') // mongoose
mongoose.set('strictQuery', false)
logger.info('connecting to', config.MONGODB_URI)
mongoose.connect(config.MONGODB_URI) // 连接数据库
  .then(() => {
    logger.info('connected to MongoDB')
  })
  .catch((error) => {
    logger.error('error connecting to MongoDB:', error.message)
  })
app.use(cors())
app.use(express.json())
app.use(middleware.requestLogger);
app.use('/api/blogs', blogsRouter);
app.use(middleware.unknownEndpoint);
app.use(middleware.errorHandler);
module.exports = app;

# index.js 启动

const app = require('./app')
const http = require('http')
const config = require('./utils/config')
const logger = require('./utils/logger')
const server = http.createServer(app);
server.listen(config.PORT, () => {
  logger.info(`Server running on port ${config.PORT}`)
})

# config.js 配置

require('dotenv').config()
const PORT = process.env.PORT;
const MONGODB_URI = process.env.MONGODB_URI;
module.exports = {
    MONGODB_URI,
    PORT
}

# logger.js 日志

const info = (...params) => {
    console.log(...params);
}
const error = (...params) => {
    console.error(...params);
}
module.exports = {
    info,
    error
}

# middleware.js 中间件

const logger = require('./logger');
const requestLogger = (request, response, next) => {
  logger.info('Method:', request.method);
  logger.info('Path:  ', request.path);
  logger.info('Body:  ', request.body);
  logger.info('---');
  next();
};
const unknownEndpoint = (request, response) => {
  response.status(404).send({ error: 'unknown endpoint' });
};
const errorHandler = (error, request, response, next) => {
  logger.error(error.message);
  if (error.name === 'CastError') {
    return response.status(400).send({ error: 'malformatted id' });
  } else if (error.name === 'ValidationError') {
    return response.status(400).json({ error: error.message });
  }
  next(error);
};
module.exports = {
    requestLogger,
    unknownEndpoint,
    errorHandler
}
更新于 阅读次数