类知乎问答系统的设计方案
一、项目概述
实现一个类似知乎的问答社区系统,支持问题、回答的发布和修改,问题拉链,支持按热度和时间序排序,回答点赞点踩以及热门问题列表。
二、结构特点
项目采用客户-服务,即 C/S 架构风格,客户端通过 http 请求访问或调用服务端的数据,服务端根据请求的类型、url 和请求体来调用不同功能。客户是主动调用的,服务是被动的。客户-服务模式的架构风格具有典型的模块化特征,降低了系统中客户和服务构件之间耦合度,提高了服务构件的可重用性。
三、接口 API
客户端与服务端之间通过 API 进行通讯,本项目采用 RESTful 风格的 API 设计。请求体和响应均采用 JSON 格式,例如:
用户登录
请求方式:POST
URL:/user/login
请求body(示例):
{
"email": "a@b.com",
"password": "123456"
}
响应body(示例):
{
"code": 0,
"data": {
"id": 1,
"token": "eyJhbGciOiJIUzI1Ni......P9tvKNYkOXFjBpudayVCN8"
},
"message": "OK"
}
其余接口的概要如下:
| 功能 | API | 请求体 | 响应 | 说明 |
|---|---|---|---|---|
| 用户登录 | POST /user/login | email, password | 用户 token | |
| 用户注册 | POST /user/register | 用户信息 | 用户 token | |
| 发送验证码 | GET /user/verify?email=x@x.com | - | ok | |
| 获取问题列表 | GET /question?cursor=123&size=10&search=xxx&orderby=time | - | 问题列表 | cursor为分页用的游标,size为条目数,search为搜索字符串,orderby为排序依据 |
| 获取问题详情 | GET /question/ | - | 问题详情 | {question_id} 为问题的id |
| 发布问题 | POST /question | 问题内容 | ok | |
| 修改问题 | PUT /question/ | 问题内容 | ok | |
| 删除问题 | DELETE /question/ | - | ok | |
| 获取回答列表 | GET /answer?qid=1&cursor=123&size=10&orderby=time | - | 问题列表 | qid为回答对应问题的id |
| 获取回答详情 | GET /answer/ | - | 回答详情 | {answer_id} 为回答的id |
| 发布回答 | POST /answer?qid=1 | 回答内容 | ok | |
| 修改回答 | PUT /answer/ | 回答内容 | ok | |
| 删除回答 | DELETE /answer/ | - | ok |
返回给客户端的响应包括了信息、状态码、和具体数据。状态码的定义如下:
var (
Ok = Result{Code: 0, Message: "OK"}
BadRequest = Result{Code: 400, Message: "Bad Request"}
ServerErr = Result{Code: 500, Message: "Server Error"}
// 100_: Authorization
EmptyAuth = Result{Code: 1001, Message: "Empty Authorization"}
AuthFormatErr = Result{Code: 1002, Message: "Authorization Format Error"}
TokenErr = Result{Code: 1003, Message: "Token Error"}
ContextErr = Result{Code: 1004, Message: "Context Error"}
UnauthorizedOpr = Result{Code: 1005, Message: "Unauthorized operation"}
// 20__: User
// 200_: User Login
UserNotFoundErr = Result{Code: 2001, Message: "User Not Found"}
PasswordNotCorrectErr = Result{Code: 2002, Message: "Password not correct"}
// 201_: User Register
EmailAlreadyExistErr = Result{Code: 2011, Message: "Email already exists"}
CreateUserErr = Result{Code: 2012, Message: "DB Create user error"}
EmailSendErr = Result{Code: 2013, Message: "Email send error"}
WrongVerificationCode = Result{Code: 2014, Message: "Wrong verification code, or code expired."}
// 21__: Question
// 210_: Get Question
QuestionNotFoundErr = Result{Code: 2101, Message: "Question Not Found"}
UpdateViewCountErr = Result{Code: 2102, Message: "Failed in updating view count"}
// 211_: Create Question
CreateQuestionErr = Result{Code: 2111, Message: "DB create question error"}
// 212_: Update Question
UpdateQuestionErr = Result{Code: 2121, Message: "DB update question error"}
// 213_: Delete Question
DeleteQuestionErr = Result{Code: 2131, Message: "DB delete question error"}
// 22__: Answer
// 220_: Get Answer
AnswerNotFoundErr = Result{Code: 2201, Message: "Answer Not Found"}
// 221_: Create Answer
CreateAnswerErr = Result{Code: 2211, Message: "DB create Answer error"}
// 222_: Update Answer
UpdateAnswerErr = Result{Code: 2221, Message: "DB update Answer error"}
// 223_: Delete Answer
DeleteAnswerErr = Result{Code: 2231, Message: "DB delete Answer error"}
)
四、视图
1. 分解视图
分解视图用软件模块勾划出系统结构,往往会通过不同抽象层级的软件模块形成层次化的结构。这里采用按功能分解的视图。
2. 依赖视图
依赖视图展现了软件模块之间的依赖关系。
3. 执行视图
执行视图展示了系统运行时的时序结构特点,这里用时序图展示执行视图。

4. 实现视图
实现视图是描述软件架构与源文件之间的映射关系。典型的实现视图可以由软件项目的源文件目录树来呈现。
5. 部署视图
部署视图是将执行实体和计算机资源建立映射关系。
五、数据库设计
1. users 用户表
| 名称 | 类型 | 注释 |
|---|---|---|
| id | int | 用户ID |
| varchar(30) | 邮箱 | |
| password | varchar(100) | 密码 |
| name | varchar(30) | 名字 |
| description | varchar(256) | 简介 |
| avatar_url | varchar(100) | 头像 |
| create_at | bigint | 创建时间 |
| update_at | bigint | 更新时间 |
2. questions 问题表
| 名称 | 类型 | 注释 |
|---|---|---|
| id | int | 问题ID |
| title | varchar(50) | 标题 |
| content | text | 内容 |
| creator_id | int | 创建问题用户的ID |
| tag | varchar(256) | 标签 |
| answer_count | int | 回答个数 |
| create_at | bigint | 创建时间 |
| update_at | bigint | 更新时间 |
3. answers 回答表
| 名称 | 类型 | 注释 |
|---|---|---|
| id | int | 问题ID |
| content | text | 内容 |
| creator_id | int | 创建回答用户的ID |
| question_id | int | 对应问题的ID |
| upvote_count | int | 点赞个数 |
| comment_count | int | 评论个数 |
| create_at | bigint | 创建时间 |
| update_at | bigint | 更新时间 |
4. comments 评论表
| 名称 | 类型 | 注释 |
|---|---|---|
| id | int | 评论ID |
| content | text | 内容 |
| creator_id | int | 创建评论用户的ID |
| question_id | int | 对应回答的ID |
| create_at | bigint | 创建时间 |
| update_at | bigint | 更新时间 |
六、运行环境和选型
- 开发语言:Go
- Web 框架:Gin
- 数据库映射框架:gorm
- 缓存:Redis
- 数据库:MySQL
- 用户验证:JWT
- 日志管理:logrus
- 服务器运行环境:Debian 10
七、核心工作机制
软件架构代表了软件系统的整体设计结构,它应该是所有这些视图的集合。理解不同角度的视图之间的映射关系和重叠部分,从而深刻理解软件架构内在的一致性和完整性,这就是系统概念原型。
下面以发布问题为例,说明系统核心工作机制。客户端应先登录,登录后将服务端返回的token保存。发布问题时,客户端携带token,并将问题信息以api文档中的格式放入请求体,发送至服务端POST /question接口。服务端首先验证token,验证成功后进行数据库操作。操作完成后返回响应信息,客户端根据响应信息和状态码进行进一步操作。

浙公网安备 33010602011771号