在构建短剧平台时,设计一个高效、可扩展的接口(API)服务是至关重要的。这不仅能提升用户体验,还能为未来的扩展和维护打下坚实基础。本文将介绍如何设计和实现这样的API服务,包括用户认证、短剧信息获取、评论管理等核心功能,并提供相应的代码示例。
技术栈选择
- 后端框架:Node.js(Express.js)
- 数据库:MongoDB(Mongoose ORM)
- 认证:JWT(JSON Web Tokens)
- 版本控制:API版本通过URL路径管理(如
/v1/
)
1. 项目初始化
首先,初始化Node.js项目并安装必要的依赖。
bash
mkdir short-drama-api |
cd short-drama-api |
npm init -y |
npm install express mongoose jsonwebtoken body-parser cors |
2. 设置Express服务器
创建一个server.js
文件,配置Express服务器和中间件。
javascript
const express = require('express'); |
const mongoose = require('mongoose'); |
const bodyParser = require('body-parser'); |
const cors = require('cors'); |
const jwt = require('jsonwebtoken'); |
const app = express(); |
const PORT = process.env.PORT || 5000; |
// Middleware |
app.use(bodyParser.json()); |
app.use(cors()); |
// MongoDB connection |
mongoose.connect('mongodb://localhost:27017/short-drama', { |
useNewUrlParser: true, |
useUnifiedTopology: true, |
}); |
const db = mongoose.connection; |
db.on('error', console.error.bind(console, 'MongoDB connection error:')); |
db.once('open', () => { |
console.log('Connected to MongoDB'); |
}); |
// Routes import (will be created later) |
app.use('/v1/auth', require('./routes/auth')); |
app.use('/v1/dramas', require('./routes/dramas')); |
app.use('/v1/comments', require('./routes/comments')); |
app.listen(PORT, () => { |
console.log(`Server is running on port ${PORT}`); |
}); |
3. 用户认证(Auth)
创建routes/auth.js
文件,实现用户注册、登录和JWT生成。
javascript
const express = require('express'); |
const bcrypt = require('bcrypt'); |
const jwt = require('jsonwebtoken'); |
const User = require('../models/User'); |
const router = express.Router(); |
// Register new user |
router.post('/register', async (req, res) => { |
const { username, password } = req.body; |
try { |
const hashedPassword = await bcrypt.hash(password, 10); |
const user = new User({ username, password: hashedPassword }); |
await user.save(); |
res.status(201).send('User registered successfully'); |
} catch (error) { |
res.status(400).send(error.message); |
} |
}); |
// Login user and generate JWT |
router.post('/login', async (req, res) => { |
const { username, password } = req.body; |
try { |
const user = await User.findOne({ username }); |
if (!user || !(await bcrypt.compare(password, user.password))) { |
return res.status(400).send('Invalid credentials'); |
} |
const token = jwt.sign({ userId: user._id }, 'your_jwt_secret_key', { expiresIn: '1h' }); |
res.json({ token }); |
} catch (error) { |
res.status(500).send('Server error'); |
} |
}); |
module.exports = router; |
4. 短剧信息管理(Dramas)
创建routes/dramas.js
文件,实现短剧信息的CRUD操作,并添加JWT验证中间件。
javascript
const express = require('express'); |
const jwt = require('jsonwebtoken'); |
const Drama = require('../models/Drama'); |
const router = express.Router(); |
const authenticateJWT = (req, res, next) => { |
const token = req.header('Authorization').replace('Bearer ', ''); |
if (!token) return res.status(401).send('Access denied'); |
try { |
const verified = jwt.verify(token, 'your_jwt_secret_key'); |
req.user = verified; |
next(); |
} catch (error) { |
res.status(400).send('Invalid token'); |
} |
}; |
// Create new drama |
router.post('/', authenticateJWT, async (req, res) => { |
const drama = new Drama(req.body); |
drama.author = req.user.userId; |
await drama.save(); |
res.status(201).send(drama); |
}); |
// Get all dramas |
router.get('/', async (req, res) => { |
const dramas = await Drama.find(); |
res.send(dramas); |
}); |
// Get drama by ID |
router.get('/:id', async (req, res) => { |
const drama = await Drama.findById(req.params.id); |
if (!drama) return res.status(404).send('Drama not found'); |
res.send(drama); |
}); |
// Update drama by ID |
router.put('/:id', authenticateJWT, async (req, res) => { |
const drama = await Drama.findByIdAndUpdate(req.params.id, req.body, { new: true, runValidators: true }); |
if (!drama) return res.status(404).send('Drama not found'); |
res.send(drama); |
}); |
// Delete drama by ID |
router.delete('/:id', authenticateJWT, async (req, res) => { |
const drama = await Drama.findByIdAndDelete(req.params.id); |
if (!drama) return res.status(404).send('Drama not found'); |
res.send('Drama deleted'); |
}); |
module.exports = router; |
5. 评论管理(Comments)
创建routes/comments.js
文件,实现评论的CRUD操作,并添加JWT验证中间件。
javascript
const express = require('express'); |
const jwt = require('jsonwebtoken'); |
const Comment = require('../models/Comment'); |
const router = express.Router(); |
const authenticateJWT = (req, res, next) => { |
const token = req.header('Authorization').replace('Bearer ', ''); |
if (!token) return res.status(401).send('Access denied'); |
try { |
const verified = jwt.verify(token, 'your_jwt_secret_key'); |
req.user = verified; |
next(); |
} catch (error) { |
res.status(400).send('Invalid token'); |
} |
}; |
// Create new comment |
router.post('/:dramaId', authenticateJWT, async (req, res) => { |
const comment = new Comment(req.body); |
comment.dramaId = req.params.dramaId; |
comment.author = req.user.userId; |
await comment.save(); |
res.status(201).send(comment); |
}); |
// Get all comments for a drama |
router.get('/:dramaId', async (req, res) => { |
const comments = await Comment.find({ dramaId: req.params.dramaId }); |
res.send(comments); |
}); |
module.exports = router; |
6. 数据模型(Models)
创建models/User.js
和models/Drama.js
以及models/Comment.js
文件,定义数据模型。
User.js
javascript
const mongoose = require('mongoose'); |
const UserSchema = new mongoose.Schema({ |
username: { type: String, required: true, unique: true }, |
password: { type: String, required: true }, |
}); |
module.exports = mongoose.model('User', UserSchema); |
Drama.js
javascript
const mongoose = require('mongoose'); |
const DramaSchema = new mongoose.Schema({ |
title: { type: String, required: true }, |
description: { type: String, required: true }, |
author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }, |
createdAt: { type: Date, default: Date.now }, |
}); |
module.exports = mongoose.model('Drama', DramaSchema); |
Comment.js
javascript
const mongoose = require('mongoose'); |
const CommentSchema = new mongoose.Schema({ |
content: { |