TypeScript-Express-MySQL-GraphQL-API 项目
这里是引用
github地址开箱即用 https://github.com/louzhaoyan/web_backend.git (包含源码源码中包含非常详细的代码注释、数据库表结构)
项目简介
这是一个使用 TypeScript, Express, MySQL 和 GraphQL 构建的 MVC 架构的示例项目。项目展示了如何利用现代技术栈创建一个灵活且可扩展的服务器应用程序。
目录结构
.
├── package.json
├── tsconfig.json
├── src
│ ├── config
│ │ └── database.ts
│ ├── controllers
│ │ ├── baseController.ts
│ │ ├── articleController.ts
│ │ └── userController.ts
│ ├── models
│ │ ├── baseModel.ts
│ │ ├── User.ts
│ │ └── Article.ts
│ ├── graphql
│ │ ├── resolvers.ts
│ │ └── typeDefs.ts
│ └── index.ts
目录结构说明
-
config: 存放数据库配置文件。
-
controllers: 存放控制器类,包含基础控制器(BaseController)和具体的控制器(UserController, ArticleController)。
-
models: 存放实体类,包含基础实体类(BaseModel)和具体的实体类(User, Article)。
-
graphql: 存放GraphQL的类型定义和解析器。
-
index.ts: 项目的入口文件,通过Express启动GraphQL服务器并连接数据库,包含会话管理中间件。
设计模式
MVC 架构
- Model: 表示数据库中的数据结构,使用 TypeORM 进行 ORM 映射。所有的实体类都继承自
BaseModel
类,以包含公共字段(如id
、createdAt
和updatedAt
)。 - Controller: 处理业务逻辑和数据操作。基础控制器
BaseController
封装了通用的 CRUD 操作,各具体控制器(如UserController
和ArticleController
)继承自BaseController
并扩展特定的业务逻辑。 - View: 通过 GraphQL 进行数据查询和变更操作,前端可以通过 GraphQL 查询和变更数据。
启动配置
环境配置
请在 src/config/database.ts
文件中配置您的数据库连接信息:
import { ConnectionOptions } from 'typeorm';
export const dbConfig: ConnectionOptions = {
type: 'mysql',
host: 'localhost',
port: 3306,
username: 'your-username',
password: 'your-password',
database: 'your-database',
synchronize: true, // 设置为 true 以自动同步数据库表结构(生产环境中请设为 false)
entities: [
__dirname + '/../models/*.ts'
],
};
项目依赖
项目依赖于以下主要包:
express
: Node.js Web 应用框架apollo-server-express
: 在 Express 中运行 Apollo Server 以支持 GraphQLtypeorm
: TypeScript 和 JavaScript 的 ORM 框架mysql
: MySQL 数据库驱动bcrypt
: 用于哈希处理密码express-session
: 用于会话管理body-parser
: 用于解析请求体cors
: 处理跨域资源共享morgan
: HTTP 请求日志中间件helmet
: 设置安全的 HTTP 头compression
: Gzip 压缩响应体csurf
: 提供 CSRF 保护multer
: 处理文件上传
安装依赖
然后,运行以下命令以安装项目依赖:
yarn install
启动项目
项目提供了两种启动方式:
-
生产模式:
运行以下命令以编译 TypeScript 并启动服务器:
yarn start
-
开发模式:
在开发模式下,使用
ts-node-dev
以实现保存编辑代码时自动更新:yarn dev
使用的中间件
-
body-parser:解析请求体,通常用于解析 JSON 和 URL 编码的数据。
-
cors:处理跨域资源共享(CORS)问题,允许来自不同源的请求。
-
morgan:HTTP 请求日志中间件,用于记录请求日志,方便调试和监控。
-
helmet:帮助你设置 HTTP 头,以增加你的应用程序的安全性。
-
compression:Gzip 压缩响应体,提高传输速度。
-
express-session:用于管理用户的会话状态。配置如下:
app.use(session({ secret: 'mySecretKey', // 用于签名会话ID的密钥 resave: false, // 是否强制保存会话,即使会话未修改 saveUninitialized: true, // 是否自动保存未初始化的会话 }));
-
csurf:提供 CSRF 保护。配置如下:
app.use(csurf());
-
multer:处理文件上传。配置如下:
const upload = multer({ dest: 'uploads/' }); app.post('/upload', upload.single('file'), (req, res) => { res.send({ filePath: req.file.path }); });
-
Apollo Server:用于处理 GraphQL 请求。配置如下:
const server = new ApolloServer({ typeDefs, resolvers, context: ({ req }) => ({ req }) // 将请求对象注入到上下文中,以便解析器使用 }); await server.start(); server.applyMiddleware({ app });
GraphQL API
项目定义了以下 GraphQL 类型和操作:
类型
User
:用户类型,包含id
,name
,email
,password
,role
字段。Article
:文章类型,包含id
,title
,content
,authorId
字段。
查询
getUser(id: ID!)
:根据ID获取单个用户。getUsers
:获取所有用户。getArticle(id: ID!)
:根据ID获取单篇文章。getArticles
:获取所有文章。
变更
registerUser(name: String!, email: String!, password: String!)
:注册新用户。createUser(name: String!, email: String!, password: String!)
:创建新用户。loginUser(email: String!, password: String!)
:用户登录。logoutUser
:用户登出。createArticle(title: String!, content: String!)
:创建新文章。updateArticle(id: ID!, title: String, content: String)
:更新文章。deleteArticle(id: ID!)
:删除文章。
数据库表结构
用户表
CREATE TABLE User (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
role VARCHAR(50) DEFAULT 'user', -- 用户角色,默认为 'user'
createdAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
文章表
CREATE TABLE Article (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
authorId INT NOT NULL,
createdAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (authorId) REFERENCES User(id) ON DELETE CASCADE
);
文件表
CREATE TABLE File (
id INT AUTO_INCREMENT PRIMARY KEY,
filePath VARCHAR(255) NOT NULL,
userId INT NOT NULL,
createdAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (userId) REFERENCES User(id) ON DELETE CASCADE
);