给前端初学者看的项目技术原理文档

从浏览器页面到后端数据库,一次看懂 Tech Blog 怎么工作。

你不需要先精通后端。只要理解“前端负责展示和交互,后端负责规则和数据,数据库负责长期保存”,就能沿着本文档读懂这个项目的主要技术链路。

01Next.js 前台
02NestJS 后端
03Prisma 数据库
04JWT 鉴权

Mental Model

先建立一个整体心智模型

把这个项目想象成一家线上杂志社:读者在前台看文章,编辑在后台管理文章,服务端像收银台和仓库管理员,数据库像档案室。

浏览器前端

负责把数据变成页面:按钮、卡片、表单、跳转、交互状态都在这里。

服务端 API

负责接收请求并做判断:能不能登录、能不能发评论、要返回哪些文章。

数据库

负责长期保存数据:用户、文章、评论、点赞、收藏都最终存在 PostgreSQL。

共享包

负责减少重复代码:多个应用共用类型和 UI,避免各写各的。

Architecture

系统总览:一个仓库里放了多个应用

这个项目是 Monorepo,意思是多个相关应用和包放在同一个代码仓库中。好处是前台、后台、后端、共享类型可以一起开发、一起校验。

apps/web

博客前台

用户打开的网页,负责首页、搜索、文章详情、登录和用户中心。

apps/admin

管理后台

管理员使用的网页,负责文章、分类、标签、用户和评论管理。

apps/api

服务端 API

NestJS 写成的后端,接收前端请求,执行业务规则,再读写数据库。

apps/android

移动端客户端

Android Kotlin + Compose 客户端,通过同一套 API 获取博客数据。

packages/shared

共享类型

用 Zod 和 TypeScript 描述跨端共用的数据结构,比如文章、用户、评论。

packages/ui

共享 UI

Web 和 Admin 可复用的按钮、标题、标签等视觉组件。

系统协作图

1

Web / Admin / Android

不同客户端负责收集用户操作,并发起 HTTP 请求。

2

NestJS API

后端按模块处理业务:文章、用户、评论、收藏等。

3

Prisma ORM

把 TypeScript 里的查询翻译成数据库能执行的 SQL。

4

PostgreSQL

保存真实数据,并在下次请求时继续提供。

Frontend

前端页面路由:URL 决定打开哪个页面

Next.js App Router 使用文件夹表示路由。比如 app/search/page.tsx 对应 /search,app/posts/[slug]/page.tsx 对应任意文章详情。

/首页

请求文章列表和分类列表,展示精选文章、分类 Tab 和文章卡片。

/search搜索

把用户输入的 q 参数传给后端,在标题、摘要、正文中做模糊检索。

/posts/[slug]文章详情

根据文章 slug 请求单篇文章,使用 marked 把 Markdown 转成 HTML。

/login登录

提交邮箱和密码,成功后把 JWT 与用户信息保存到浏览器本地状态。

/profile用户中心

带着 JWT 请求当前用户资料,并展示收藏等个性化信息。

/tech-docs技术原理

当前页面,用通俗解释和图示说明整个项目如何工作。

Data Flow

用户访问文章列表时发生了什么

从前端视角看,你调用的是 getPosts;从全栈视角看,它背后是一条从浏览器到数据库再回来的链路。

1

打开首页

浏览器请求 /,Next.js 执行 app/page.tsx,准备渲染首页。

2

请求 API

getPosts({ pageSize: 18 }) 拼出 /posts?pageSize=18,并发请求分类。

3

后端查询

PostsController 调用 PostsService,Prisma 查询 PUBLISHED 状态文章。

4

渲染卡片

API 返回 JSON,前端把 items 交给 PostCard 组件显示。

请求链路图

1
Browser
2
Next.js
3
GET /posts
4
NestJS + Prisma
5
PostgreSQL

Backend

后端 API 分层:Controller 接请求,Service 做业务

NestJS 常见结构是 Module 组织功能,Controller 暴露 HTTP 接口,Service 写业务逻辑,PrismaService 负责连接数据库。

AuthModule

注册、登录、生成 JWT、校验用户身份。

UsersModule

读取当前用户资料,管理用户相关信息。

PostsModule

文章列表、详情、创建、更新、归档、点赞状态。

CategoriesModule

文章分类的查询和管理。

TagsModule

标签的查询和管理。

FavoritesModule

收藏、取消收藏和收藏数量维护。

CommentsModule

评论发布、展示和管理。

AssetsModule

上传图片等静态资源。

Controller

像前台接待员,负责识别请求路径、参数和请求体,例如 GET /posts。

Service

像业务负责人,决定如何查询、创建、更新、校验和序列化数据。

PrismaService

像数据库翻译员,把代码里的对象查询转换成数据库操作。

Authentication

登录鉴权:JWT 是一张可验证的临时通行证

用户输入密码后,后端不会明文保存密码,而是保存 bcrypt 哈希。登录成功后,后端签发 JWT,前端后续请求把它放到 Authorization 头里。

1

提交账号密码

前端把邮箱和密码提交到 /auth/login 或 /auth/register。

2

校验密码

后端用 bcrypt.compare 比较用户输入与数据库里的 passwordHash。

3

签发 JWT

JwtService 把用户 id、email、role 签进 accessToken。

4

Guard 放行

访问受保护接口时,JwtAuthGuard 验证 token,RolesGuard 判断角色。

密码哈希

数据库保存 passwordHash,而不是原始密码。

Bearer Token

请求头格式是 Authorization: Bearer accessToken。

角色权限

管理员接口要求 ADMIN,普通用户不能直接调用。

Database

核心数据模型:理解接口数据从哪里来

前端拿到的文章卡片不是凭空生成的,它来自数据库中的多张表。Prisma schema 描述了每张表有什么字段,以及表之间怎么关联。

User

关键字段

email、passwordHash、name、role

关系

作者、评论者、点赞者、收藏者

Post

关键字段

slug、title、excerpt、contentMarkdown、status

关系

属于作者,可关联分类、标签、评论、收藏、点赞

Category

关键字段

name、slug、sortOrder

关系

一类文章的集合

Tag

关键字段

name、slug

关系

通过 PostTag 与多篇文章关联

Comment

关键字段

content、status、parentId

关系

属于文章和用户,也可以形成回复树

Favorite / Like

关键字段

userId、postId

关系

记录某个用户是否收藏或点赞某篇文章

简化关系图

User
→ 写作 →
Post
→ 归类 →
Category
→ 打标签 →
Tag
User
→ 点赞/收藏 →
Post
→ 拥有 →
Comment

Clients

管理后台和 Android:不同入口,共用同一个后端

前台、后台、移动端不是三套完全独立系统。它们可以有不同界面,但核心数据都来自 apps/api,所以后端接口和共享类型尤其重要。

博客前台

主要服务读者:浏览文章、搜索、登录、收藏、点赞、评论。

管理后台

主要服务管理员:创建文章、维护分类标签、审核评论、管理用户。

Android 客户端

主要服务移动端用户:用原生界面消费同一批文章和用户数据。

Deployment

线上发布:让任意地方的用户都能通过网址访问

本地开发时,服务只在你的电脑上运行。要让公网用户访问,需要把前台、后台、后端和数据库部署到线上,并配置域名、HTTPS 和环境变量。

推荐最小上线架构

your-domain.com

博客前台,对应 apps/web,让普通用户浏览文章和技术文档。

admin.your-domain.com

管理后台,对应 apps/admin,让管理员维护文章、分类、标签和评论。

api.your-domain.com/api

后端接口,对应 apps/api,给前台、后台、Android 提供数据。

PostgreSQL

线上数据库,保存用户、文章、评论、收藏、点赞等真实数据。

1

准备云服务器和域名

购买或准备 Ubuntu 云服务器,开放 80、443、22 端口;把 your-domain.com、admin.your-domain.com、api.your-domain.com 解析到服务器公网 IP。

2

部署线上 PostgreSQL

创建线上数据库,配置 DATABASE_URL,执行 Prisma generate、migrate,首次部署可按需执行 seed 写入默认管理员和示例数据。

3

部署 NestJS API

发布 apps/api,配置 DATABASE_URL、JWT_SECRET、PORT,让服务通过 https://api.your-domain.com/api 对外提供接口。

4

部署 Next.js 前台和后台

发布 apps/web 和 apps/admin,把 NEXT_PUBLIC_API_BASE_URL 指向 https://api.your-domain.com/api。

5

配置 Nginx 和 HTTPS

用 Nginx 把三个域名反向代理到 web、admin、api 服务端口,再用 Certbot 申请并自动续期 HTTPS 证书。

6

完成上线验收

逐个检查首页、技术文档、搜索、文章详情、登录、收藏点赞评论、管理后台和 Swagger 是否正常。

Docker Compose 发布思路

postgres 数据库
api 后端服务
web 前台服务
admin 后台服务

生产环境可以新增 docker-compose.prod.yml,并分别给 apps/api、apps/web、apps/admin 准备 Dockerfile。发布时先启动数据库,再执行 Prisma 迁移,最后启动 API、Web 和 Admin。

常用发布命令顺序

pnpm install
pnpm db:generate
pnpm db:migrate
pnpm build
启动 API、Web、Admin 服务

上线安全检查

  • JWT_SECRET 必须换成足够长的随机字符串。
  • 数据库密码不能使用示例密码,PostgreSQL 不要暴露公网 5432 端口。
  • 不要把 .env 提交到 Git 仓库。
  • 默认管理员密码上线后立刻修改。
  • 正式环境要定期备份数据库。

上线后逐项验收

依次访问 https://your-domain.com、/tech-docs、/search、/posts/某篇文章slug、https://api.your-domain.com/api/posts、https://api.your-domain.com/docs、https://admin.your-domain.com,并检查登录、搜索、文章详情、收藏点赞评论和后台管理是否正常。

Monitoring

线上监控:健康检查与自动修复

部署完成后,服务可能因为内存溢出、数据库断连、配置错误等原因崩溃。health-check.sh 脚本定期检查所有关键进程,发现异常自动修复,修复失败则触发完整重部署。

1

检测进程

遍历 PM2 进程、PostgreSQL 容器、Nginx 服务,确认每个组件的运行状态。

2

检查日志

curl 测试 API 和 Web 端点,确认服务能正常响应 HTTP 请求。

3

尝试重启

对单个失败组件执行 pm2 restart 或 docker restart,等几秒后重新检测。

4

完整重部署

如果单组件重启仍失败,自动执行 deploy.sh 做一次完整的代码拉取、构建和发布。

检查项与修复策略

PM2 进程

目标:tech-blog-api / web / admin

检测:pm2 jlist 检查 status 是否为 online

修复:pm2 restart <name>

PostgreSQL

目标:Docker 容器 tech-blog-postgres

检测:docker inspect + pg_isready

修复:docker restart tech-blog-postgres

Nginx

目标:反向代理服务

检测:systemctl is-active nginx

修复:systemctl restart nginx

API 可用性

目标:http://127.0.0.1:4000/api/posts

检测:curl 请求是否返回 200

修复:触发 deploy.sh 完整重部署

Web 可用性

目标:http://127.0.0.1:3000

检测:curl 请求是否返回 200

修复:触发 deploy.sh 完整重部署

配置定时检查

在服务器上添加 cron 任务,每 5 分钟自动执行一次健康检查:

crontab -e
*/5 * * * * bash /opt/tech-blog/app/scripts/health-check.sh >> /var/log/tech-blog-health.log 2>&1

常用运维命令

pm2 status — 查看所有 PM2 进程状态
pm2 logs — 查看实时日志
docker ps — 查看运行中的容器
tail -f /var/log/tech-blog-health.log — 查看健康检查日志
bash scripts/health-check.sh --dry-run — 模拟检查,不执行修复

Maintenance

后续修改时要同步维护这份文档

技术文档不是一次性页面。只要功能、接口、数据模型或权限流程变了,就应该把这里当作项目说明书一起更新。

同步更新清单

  • 新增页面或改路由时,同步更新“前端页面路由”章节。
  • 新增 API、修改接口参数或返回值时,同步更新“后端 API 分层”和“请求链路图”。
  • 修改 Prisma model、字段或关联关系时,同步更新“核心数据模型”。
  • 修改登录、权限、Token 存储逻辑时,同步更新“登录鉴权流程”。
  • 新增端侧应用或共享包职责变化时,同步更新“系统总览”。
  • 新增监控检查项或修改自动修复逻辑时,同步更新“线上监控”章节。

推荐修改流程

先改代码,再跑类型检查或构建,最后回到本页检查相关章节是否仍然准确。这样以后新同学读文档时,不会被过期说明误导。

返回博客首页