引言
❝如何使用Node.js、Koa和MySQL构建一个强大的前端服务框架。
技术栈概览
❝Node.js和Koa: 使用Node.js作为服务器端运行环境,Koa作为轻量级的Web框架,提供高效的中间件机制。
❝MySQL: 作为关系型数据库,用于数据存储和检索。
目录结构
node-server-template/
|-- node_modules/ # 依赖项
|-- src/ # 源代码
| |-- config/ # 存放配置文件,可能包含一些环境配置、数据库连接配置等
| |-- controller/ # 存放控制器文件,处理请求和响应逻辑
| |-- db/ # 存放与数据库相关的文件,可能包含数据库连接、模型定义等
| |-- log/ # 存放日志文件,记录应用程序的运行日志
| |-- routes/ # 存放路由文件,定义应用的不同路由和它们对应的控制器
| |-- services/ # 存放业务逻辑的服务文件,处理业务逻辑,与控制器分离
| |-- sql/ # 存放 SQL 查询文件或数据库脚本
| |-- utils/ # 存放工具函数和通用功能函数
| |-- index.js # 项目的入口文件,可能包含应用程序的启动逻辑
|-- .gitignore # Git 忽略文件配置
|-- package.json # 项目配置文件
|-- README.md # 项目文档
|-- webpack.config.js # Babel 配置文件
路由组合与统一输出 Koa Router
❝使用Koa Router实现路由组合,确保代码结构清晰有序。统一输出格式,使得前后端交互更加一致。
// loginRouter.js
import Router from 'koa-router'
import { loginController } from '../../controller/loginController'
const router = new Router()
router.prefix('/login')
router.post('/loginIn', loginController.loginIn)
router.post('/loginInSys', loginController.loginInSys)
export default router
// route.js
import combineRoutes from 'koa-combine-routers'
import systemRouter from './modules/systemRouter.js'
// import loginRouter from './modules/loginRouter.js'
// import wallpaperController from './modules/wallpaperRouter.js'
export default combineRoutes(loginRouter)
JWT认证
❝使用jwt-simple (JWT)实现身份验证,确保安全性和用户身份的一致性。
import { jwtDevConfig, jwtConfig } from "../config/jwt.config"
import jwt from 'jwt-simple'
const EXPIRES_TIME = process.env.NODE_ENV === 'production' ? jwtConfig.expiresTime : jwtDevConfig.expiresTime
const SECRET = process.env.NODE_ENV === 'production' ? jwtConfig.secret : jwtDevConfig.secret
export const generateToken = (userName, userId) => {
const payload = {
exp: Date.now() + EXPIRES_TIME,
name: userName,
id: userId
}
return jwt.encode(payload, SECRET)
}
export const getUserNameByToken = (token) => {
return jwt.decode(token, SECRET)
}
export const refreshNewToken = (token) => {
let payload = jwt.decode(token.split(' ')[1], SECRET)
if (payload) {
return generateToken(payload.name)
} else {
return null
}
}
CORS跨域处理
❝使用Koa CORS中间件处理跨域请求,确保前端可以安全地访问后端服务。
const cors = require('@koa/cors');
app.use(cors());
全局日志管理
❝通过集成日志管理工具,记录关键事件和错误,以便更好地监控和排除问题。
const path = require('path');
const log4js = require('koa-log4');
const RUNTIME_PATH = path.resolve(__dirname, '../');
const LOG_PATH = path.join(RUNTIME_PATH, 'log');
log4js.configure({
// 日志的输出
appenders: {
access: {
type: 'dateFile',
pattern: '-yyyy-MM-dd.log', //生成文件的规则
alwaysIncludePattern: true, // 文件名始终以日期区分
encoding: 'utf-8',
filename: path.join(LOG_PATH, 'access.log') //生成文件名
},
application: {
type: 'dateFile',
pattern: '-yyyy-MM-dd.log',
alwaysIncludePattern: true,
encoding: 'utf-8',
filename: path.join(LOG_PATH, 'application.log')
},
out: {
type: 'console'
}
},
categories: {
default: { appenders: [ 'out' ], level: 'info' },
access: { appenders: [ 'access' ], level: 'info' },
application: { appenders: [ 'application' ], level: 'all'}
}
});
// getLogger 传参指定的是类型
exports.accessLogger = () => log4js.koaLogger(log4js.getLogger('access')); // 记录所有访问级别的日志
exports.logger = log4js.getLogger('application');
统一返回对象封装
❝封装统一的返回对象,包含成功标志和数据,提高代码的可维护性和一致性。
export const returnJson = (code=200, data, message) => {
return {
code: code,
data: data,
message: message
}
}
MySQL分环境配置
❝根据环境变量配置MySQL连接,实现不同环境下的数据库切换。
// 开发环境
export const mysqlDevConfig = {
host: '172.16.119.132',
port: '3306',
user: 'root',
password: 'mysql',
database: 'db_wallpaper',
timezone: 'SYSTEM',
acquireTimeout: 10000,
waitForConnection: true,
connectionLimit: 10,
queueLimit: 0
}
// 生产环境
export const mysqlConfig = {
host: '172.16.119.132',
port: '3306',
user: 'root',
password: 'mysql',
database: 'db_wallpaper',
timezone: 'SYSTEM',
acquireTimeout: 10000,
waitForConnection: true,
connectionLimit: 10,
queueLimit: 0
}
SQL与ORM对比
❝SQL、Sequelize与TypeORM对比。
// SQL
import { db } from '../db/index'
import { returnJson } from '../utils/common'
import { logger } from '../utils/logger'
const loginIn = async (params) => {
try {
const result = await isAlreadyUserName(params)
if (result.code === 200) {
return result
} else {
const queryResult = await db.query('insert into user_info(openid) values(?)', [params.openid])
if (queryResult.data.affectedRows) {
return returnJson(200, params.openid, '用户注册并登录成功')
} else {
return returnJson(-1, null, '用户注册失败')
}
}
} catch (error) {
logger.error('登录出错:', error)
return returnJson(-1, null, '登录出错,请稍后重试')
}
}
// ORM
// Sequelize Example
const { Sequelize, DataTypes } = require('sequelize');
const sequelize = new Sequelize('mysql://user:pass@localhost:3306/database');
const User = sequelize.define('User', {
username: DataTypes.STRING,
password: DataTypes.STRING
});
// TypeORM Example
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
username: string;
@Column()
password: string;
}
源码
❝源码在小程序自行获取,公众号: 牛马圈 小程序: 牛马圈分享
本文由 mdnice 多平台发布