9ba916643ec1d1672bdbabb3367c68fb76d29b54
feedsystem_video_go
基于 Go 的视频 Feed 系统后端,提供账号、视频、点赞、评论、关注(Social)与 Feed 等接口。默认技术栈:Gin + GORM + MySQL + JWT (+ Redis 可选)。
仓库内附 Postman Collection(test/postman.json),可用于手工/批量调试接口,并包含部分断言脚本。
目录结构
cmd/:程序入口(cmd/main.go)configs/:YAML 配置(configs/config.yaml)internal/account/:账号模块internal/video/:视频 / 点赞 / 评论模块internal/social/:关注模块internal/feed/:Feed 模块internal/http/:Gin 路由注册(internal/http/router.go)internal/middleware/:JWT 中间件(internal/middleware/jwt.go)test/:Postman Collection(推荐使用test/postman.json)
快速开始
- 准备 MySQL 并创建数据库(库名/账号密码在
configs/config.yaml配置)。 - 安装依赖:
go mod tidy - 启动服务:
go run ./cmd - Postman 导入:
test/postman.json(默认host=http://localhost:8080)
启动时会自动执行
AutoMigrate(见internal/db/db.go)。
Redis 为可选依赖:未配置/不可用时服务仍可启动,但不会启用缓存加速。
配置
配置文件:configs/config.yaml
server:
port: 8080
database:
host: localhost
port: 3306
user: root
password: 123456
dbname: feedsystem
可选环境变量:
JWT_SECRET:JWT 签名密钥;不设置则使用默认值(仅建议本地调试)。REDIS_ADDR:Redis 地址(默认127.0.0.1:6379),用于缓存/加速(连不上会自动降级为不使用缓存)。REDIS_PASSWORD:Redis 密码(可选)。REDIS_DB:Redis DB 库号(默认0)。
认证说明(与代码一致)
- 认证 Header:
Authorization: Bearer <jwt> - 校验流程(见
internal/middleware/jwt.go):- 校验 JWT 签名与过期时间。
- 校验该账号“当前有效 token”:优先查 Redis key
account:<accountID>;Redis 读不到/失败则回退查 DB 的account.token;DB 校验通过会回填 Redis(自愈)。
- 因此:
- 同一账号再次登录会覆盖 token(旧 token 立即失效)
/account/logout会清空 token(立即失效)/account/changePassword成功后会清空 token(需要重新登录)/account/rename成功后会返回新 token 并写回数据库(旧 token 立即失效)
- Feed 接口使用“软鉴权”(
SoftJWTAuth):可以不带 token;但如果带了Authorization,必须是合法且未撤销的 token,否则返回401。
Redis 缓存/加速点(可选)
- 鉴权 token 校验:Redis key
account:<accountID>(TTL 24h)。 - Feed 匿名流缓存:
/feed/listLatest(短 TTL,见internal/feed/service.go)。 - 视频详情缓存:
/video/getDetail(见internal/video/video_service.go)。
手动自测(推荐)
POST /account/register→POST /account/login拿到token。- 带
Authorization: Bearer <token>调用任意 JWT 保护接口(如/like/isLiked)应返回200。 POST /account/logout后,用旧 token 调用保护接口应返回401。- Redis 兜底:停掉 Redis 后再请求保护接口应仍可通过(走 DB);Redis 恢复后再请求会回填 Redis。
Postman 建议测试流程
使用一体化集合:test/postman.json(含预置变量与自动保存脚本)。
建议运行顺序:
- Account → Register Account
- Account → Login (save jwt_token)
- Account → Find By Username (save accountId / vloggerId)
- Social → Follow / Get All Followers / Get All Vloggers / Unfollow(可选)
- Video → Publish Video(会保存
publishedVideoId) - Feed → List By Following(可选;需要带 token 才是“关注流”)
- Like / Comment / Feed 其它接口(可选)
注意:执行 Account/Rename 后,集合会把响应里的 token 覆盖到 jwt_token,否则后续鉴权接口会因为旧 token 失效而 401。
API(路由与鉴权)
路由注册见 internal/http/router.go,以下均为 POST + JSON body。
账号(/account)
| 路径 | 是否需要 JWT | 说明 |
|---|---|---|
/account/register |
否 | {"username":"alice","password":"pass123"} |
/account/login |
否 | {"username":"alice","password":"pass123"} → {"token":"..."} |
/account/changePassword |
否 | {"username":"alice","old_password":"pass123","new_password":"newpass456"}(成功会登出) |
/account/findByID |
否 | {"id":1} |
/account/findByUsername |
否 | {"username":"alice"} |
/account/rename |
是 | {"new_username":"alice_new"} → {"token":"..."}(返回新 token) |
/account/logout |
是 | {} |
视频(/video)
| 路径 | 是否需要 JWT | 说明 |
|---|---|---|
/video/listByAuthorID |
否 | {"author_id":1} |
/video/getDetail |
否 | {"id":1} |
/video/publish |
是 | {"title":"demo","description":"...","play_url":"http://...","cover_url":"http://..."}(必填:title/play_url/cover_url) |
点赞(/like)
| 路径 | 是否需要 JWT | 说明 |
|---|---|---|
/like/isLiked |
是 | {"video_id":1} |
/like/like |
是 | {"video_id":1} |
/like/unlike |
是 | {"video_id":1} |
评论(/comment)
| 路径 | 是否需要 JWT | 说明 |
|---|---|---|
/comment/listAll |
否 | {"video_id":1} |
/comment/publish |
是 | {"video_id":1,"content":"hello"} |
/comment/delete |
是 | {"comment_id":1}(仅作者可删) |
关注(/social,JWT 保护)
| 路径 | 是否需要 JWT | 说明 |
|---|---|---|
/social/follow |
是 | {"vlogger_id":1} |
/social/unfollow |
是 | {"vlogger_id":1} |
/social/getAllFollowers |
是 | {"vlogger_id":1}(可为空:默认取当前登录账号) |
/social/getAllVloggers |
是 | {"follower_id":1}(可为空:默认取当前登录账号) |
Feed(/feed,软鉴权)
| 路径 | 是否需要 JWT | 说明 |
|---|---|---|
/feed/listLatest |
否(可选 JWT) | {"limit":10,"latest_time":0} |
/feed/listLikesCount |
否(可选 JWT) | {"limit":10,"likes_count_before":0,"id_before":0} |
/feed/listByFollowing |
是 | {"limit":10} |
分页说明:
/feed/listLatest:latest_time为 Unix 秒时间戳;响应next_time也为 Unix 秒(0表示无下一页)。/feed/listLikesCount:使用复合游标分页:请求携带likes_count_before+id_before(两者一起用;全为0表示第一页);响应返回next_likes_count_before+next_id_before用于下一页请求。
数据表(自动迁移)
启动时会执行 AutoMigrate(internal/db/db.go),创建/更新:Account、Video、Like、Comment、Social。
Description
Languages
Go
81.8%
TypeScript
12.9%
Shell
2.7%
CSS
1.7%
Dockerfile
0.8%
Other
0.1%