MongoDB小课堂: 构建高可用股票仓位管理API服务(Express+Mongoose全栈实战)

背景:服务架构设计原理


1 ) 核心目标
为股票交易场景构建安全的仓位管理API服务,通过中间层封装MongoDB操作,实现账户、股票代码、数量、价格等核心数据的全生命周期管理。解决直接暴露数据库导致的安全风险,提供标准化的CRUD接口。

2 ) 架构优势

客户端
路由层
控制器层
模型层
MongoDB数据库
  • 安全隔离:中间件架构防止直接数据库访问
  • 解耦设计:Model-Controller-Router分层(关注点分离)
  • 标准化交互:RESTful接口规范(POST/GET/PUT/DELETE)
  • 扩展性:可无缝集成身份验证、缓存等模块

要点

  • 生产环境必须通过服务层封装数据库操作,避免SQL注入、未授权访问等风险,同时保障数据一致性。

实现步骤与技术细节


1 ) 环境准备

工具作用安装命令
Node.js服务端运行时官网下载
MongoDB文档数据库docker run -p 27017:27017 mongo
PostmanAPI测试工具官网下载

2 ) 项目初始化

创建项目并安装依赖
mkdir position-service && cd position-service
npm init -y
npm install express mongoose body-parser
  • 关键依赖:
    • express:轻量级Web框架
    • mongoose:MongoDB ODM(对象文档映射)
    • body-parser:HTTP请求体解析中间件

3 ) 三层架构实现

3.1 模型层(Model)

// models/position.js
const mongoose = require('mongoose');
 
const positionSchema = new mongoose.Schema({
  account: { 
    type: String, 
    required: true,  // 强制字段验证
    minlength: 3     // 账户名最小长度
  },
  stock: { 
    type: String, 
    required: true,
    match: /^[A-Z]{1,5}$/  // 股票代码格式校验
  },
  quantity: { 
    type: Number, 
    required: true,
    min: [1, '数量不能小于1']  // 自定义错误提示
  },
  price: { 
    type: Number, 
    required: true,
    min: 0.01 
  }
});
 
module.exports = mongoose.model('Position', positionSchema);

3.2 控制器层(Controller)

// controllers/positionController.js
const Position = require('../models/position');
 
// 创建仓位(异步异常处理)
exports.createPosition = async (req, res) => {
  try {
    const newPosition = new Position(req.body);
    await newPosition.save();
    res.status(201).json({ 
      message: "仓位记录添加成功",
      id: newPosition._id  // 返回文档ID
    });
  } catch (err) {
    res.status(400).json({ 
      error: "数据校验失败",
      details: err.errors 
    });
  }
};
 
// 查询仓位(支持分页扩展)
exports.queryPositions = async (req, res) => {
  const { account, page=1, limit=10 } = req.query;
  try {
    const positions = await Position.find({ account })
      .skip((page-1)*limit)
      .limit(parseInt(limit));
    res.status(200).json(positions);
  } catch (err) {
    res.status(500).json({ error: "数据库查询异常" });
  }
};

3.3 路由层(Router)

// routes/positionRoutes.js
const router = require('express').Router();
const controller = require('../controllers/positionController');
 
router.post('/', controller.createPosition);       // POST /position
router.get('/', controller.queryPositions);         // GET /position?account=001 
router.put('/:id', controller.updatePosition);     // PUT /position/507f1f77bcf86cd7
router.delete('/:id', controller.deletePosition);  // DELETE /position/507f1f77bcf86cd7 
 
module.exports = router;
端点格式HTTP方法功能参数传递方式
/positionPOST创建仓位Body(JSON)
/position?account=001GET查询仓位Query String
/position/:idPUT更新仓位URL Params + Body
/position/:idDELETE删除仓位URL Params

4 ) 服务集成与启动

// app.js
const express = require('express');
const mongoose = require('mongoose');
const positionRoutes = require('./routes/positionRoutes');
 
const app = express();
app.use(express.json());  // 替代body-parser
 
// 生产环境连接配置(带认证)
mongoose.connect(process.env.DB_URI || 'mongodb://localhost:27017/demo', {
  useNewUrlParser: true,
  useUnifiedTopology: true,
  authSource: 'admin',
  user: process.env.DB_USER,
  pass: process.env.DB_PASS
});
 
// 全局错误处理中间件
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).json({ code: 'SERVER_ERROR', message: '服务端异常' });
});
 
app.use('/position', positionRoutes);
app.listen(8888, () => console.log('服务运行中: http://localhost:8888'));

要点

  1. 使用环境变量(process.env)管理敏感信息
  2. Schema验证比应用层验证更接近数据源
  3. 统一的错误处理中间件可捕获所有未处理异常

案例:服务测试与验证


1 ) 测试用例(Postman示例)

操作请求示例预期响应
创建POST /position
Body: {"account":"001","stock":"AMZN","quantity":1,"price":1650}
201: {"message":"仓位记录添加成功", "id":"xxx"}
查询GET /position?account=001&page=1&limit=5200: [{account:"001", ...}]
更新PUT /position/507f1f77bcf86cd7
Body: {"quantity":2}
200: {"message":"仓位记录更新成功"}
删除DELETE /position/507f1f77bcf86cd7200: {"message":"仓位记录删除成功"}

2 ) 自动化测试脚本

// test/api.test.js (使用Jest + Supertest)
const request = require('supertest');
const app = require('../app');
 
describe('仓位管理API', () => {
  let positionId;
  
  test('创建仓位', async () => {
    const res = await request(app)
      .post('/position')
      .send({account: "TEST", stock: "TSLA", quantity: 10, price: 250});
    expect(res.statusCode).toEqual(201);
    positionId = res.body.id; // 保存ID用于后续操作
  });
 
  test('更新仓位', async () => {
    const res = await request(app)
      .put(`/position/${positionId}`)
      .send({ quantity: 15 });
    expect(res.statusCode).toEqual(200);
  });
});

要点

  1. Postman适合手动测试接口契约
  2. Jest+Supertest可实现自动化回归测试
  3. 测试覆盖率应包含异常路径(如非法参数)

部署方案


1 ) Docker容器化部署示例

FROM node:18
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 8888
CMD ["node", "app.js"]

2 ) 性能压测

# 使用Artillery进行负载测试 
npm install -g artillery
artillery quick --count 50 -n 20 http://localhost:8888/position

3 )灾备方案

  • MongoDB副本集配置指南
  • 服务端日志持久化(ELK方案)

4 )前端集成示例

// React组件调用示例
const fetchPositions = async () => {
  const res = await fetch('/position?account=001');
  return res.json(); 
};

5 )限流保护

// 添加速率限制中间件
const rateLimit = require('express-rate-limit');
app.use('/position', rateLimit({ 
  windowMs: 15*60*1000, 
  max: 100 
}));

结论与关键知识点


1 ) 核心总结

  1. 安全架构:服务层封装使数据库远离客户端直接访问
  2. 高效开发:Mongoose ODM提供Schema验证、链式查询等高级功能
  3. 生产就绪:错误处理、环境变量、连接池优化保障稳定性

2 ) 生产级优化建议

  • 安全加固:
    // 启用HTTPS和CORS
    const https = require('https');
    const fs = require('fs');
    const server = https.createServer({
      key: fs.readFileSync('private.key'),
      cert: fs.readFileSync('certificate.crt')
    }, app);
    
  • 性能优化:
    // 连接池配置
    mongoose.connect(uri, {
      poolSize: 15, // 最大连接数
      socketTimeoutMS: 45000 
    });
    
  • 可观测性:
    • 添加日志中间件(如Winston)
    • 集成Prometheus监控指标

3 ) 扩展方向

模块实现方案业务价值
身份认证JWT + Passport.js防止未授权操作
缓存加速Redis缓存高频查询结果降低数据库负载
实时通知WebSocket推送仓位变更提升交易体验
文档自动化Swagger生成API文档降低对接成本

4 ) MongoDB vs 关系型数据库操作对比

在这里插入图片描述

-- SQL等效操作示例 
UPDATE positions 
SET quantity = 15 
WHERE id = '507f1f77bcf86cd7'; -- 需精确控制事务

要点

  1. MongoDB适合频繁变更的交易数据模型
  2. 关系型数据库在复杂事务中更有优势
  3. 混合架构(MongoDB+Redis)可兼顾性能与灵活性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值