全栈开发
概述
全栈开发涵盖从前端用户界面到后端服务、数据库和 API 设计的完整技术栈。本文梳理现代全栈开发的核心技术和最佳实践。
1. 全栈架构概览
graph TB
subgraph 前端 Frontend
A[浏览器/客户端]
A1[React / Vue]
A2[HTML/CSS/JS]
end
subgraph API层
B[API Gateway / 反向代理]
B1[RESTful API / GraphQL]
end
subgraph 后端 Backend
C1[Flask / FastAPI]
C2[Spring Boot]
C3[业务逻辑层]
end
subgraph 数据层
D1[(PostgreSQL)]
D2[(MongoDB)]
D3[(Redis Cache)]
end
A --> A1 --> A2
A2 -->|HTTP/WebSocket| B
B --> B1
B1 --> C1
B1 --> C2
C1 --> C3
C2 --> C3
C3 --> D1
C3 --> D2
C3 --> D3
2. 前端框架
2.1 React
React 是 Facebook 开发的 UI 库,核心理念:组件化 + 声明式 + 单向数据流。
函数组件与 Hooks:
import { useState, useEffect, useCallback } from 'react';
function UserList() {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
const [search, setSearch] = useState('');
useEffect(() => {
// 副作用:获取数据
fetch('/api/users')
.then(res => res.json())
.then(data => {
setUsers(data);
setLoading(false);
});
}, []); // 空依赖 = 只在挂载时执行
const filteredUsers = users.filter(u =>
u.name.toLowerCase().includes(search.toLowerCase())
);
if (loading) return <div>Loading...</div>;
return (
<div>
<input
value={search}
onChange={e => setSearch(e.target.value)}
placeholder="Search users..."
/>
<ul>
{filteredUsers.map(user => (
<UserCard key={user.id} user={user} />
))}
</ul>
</div>
);
}
function UserCard({ user }) {
return (
<li className="user-card">
<h3>{user.name}</h3>
<p>{user.email}</p>
</li>
);
}
常用 Hooks:
| Hook | 用途 |
|---|---|
useState |
状态管理 |
useEffect |
副作用(数据获取、订阅) |
useContext |
跨组件状态共享 |
useReducer |
复杂状态逻辑 |
useMemo |
计算结果缓存 |
useCallback |
函数引用缓存 |
useRef |
DOM 引用 / 可变值 |
状态管理:
- Context API:简单的全局状态
- Redux / Zustand:复杂状态管理
- React Query / SWR:服务端状态管理
2.2 Vue(Composition API)
<script setup>
import { ref, computed, onMounted } from 'vue';
const users = ref([]);
const search = ref('');
const filteredUsers = computed(() =>
users.value.filter(u =>
u.name.toLowerCase().includes(search.value.toLowerCase())
)
);
onMounted(async () => {
const res = await fetch('/api/users');
users.value = await res.json();
});
</script>
<template>
<input v-model="search" placeholder="Search..." />
<ul>
<li v-for="user in filteredUsers" :key="user.id">
{{ user.name }} - {{ user.email }}
</li>
</ul>
</template>
2.3 React vs Vue
| 维度 | React | Vue |
|---|---|---|
| 模板 | JSX(JS 中写 HTML) | Template(HTML 中写逻辑) |
| 响应式 | 手动 setState | 自动依赖追踪 |
| 生态 | 丰富但碎片化 | 官方统一(Router, Pinia) |
| 学习曲线 | 中等 | 较低 |
| 适用场景 | 大型复杂应用 | 中小型应用,快速开发 |
3. 后端框架
3.1 Flask(Python 微框架)
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/api/users', methods=['GET'])
def get_users():
page = request.args.get('page', 1, type=int)
per_page = request.args.get('per_page', 20, type=int)
users = User.query.paginate(page=page, per_page=per_page)
return jsonify({
'users': [u.to_dict() for u in users.items],
'total': users.total,
'pages': users.pages
})
@app.route('/api/users', methods=['POST'])
def create_user():
data = request.get_json()
user = User(name=data['name'], email=data['email'])
db.session.add(user)
db.session.commit()
return jsonify(user.to_dict()), 201
3.2 FastAPI(Python 现代框架)
from fastapi import FastAPI, HTTPException, Depends
from pydantic import BaseModel, EmailStr
from typing import Optional
app = FastAPI()
class UserCreate(BaseModel):
name: str
email: EmailStr
age: Optional[int] = None
class UserResponse(BaseModel):
id: int
name: str
email: str
@app.get("/api/users", response_model=list[UserResponse])
async def get_users(skip: int = 0, limit: int = 20):
return await User.find_all(skip=skip, limit=limit)
@app.post("/api/users", response_model=UserResponse, status_code=201)
async def create_user(user: UserCreate):
# Pydantic 自动验证请求体
db_user = await User.find_by_email(user.email)
if db_user:
raise HTTPException(status_code=400, detail="Email already registered")
return await User.create(**user.dict())
FastAPI 优势:
- 自动 API 文档(Swagger UI + ReDoc)
- 基于 Pydantic 的类型验证
- 原生 async/await 支持
- 性能接近 Go/Node.js
3.3 Spring Boot(Java)
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping
public ResponseEntity<Page<UserDTO>> getUsers(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "20") int size) {
return ResponseEntity.ok(userService.findAll(PageRequest.of(page, size)));
}
@PostMapping
public ResponseEntity<UserDTO> createUser(@Valid @RequestBody CreateUserRequest request) {
UserDTO user = userService.create(request);
return ResponseEntity.status(HttpStatus.CREATED).body(user);
}
}
4. RESTful API 设计
4.1 HTTP 方法
| 方法 | 语义 | 幂等 | 示例 |
|---|---|---|---|
| GET | 读取资源 | 是 | GET /api/users/123 |
| POST | 创建资源 | 否 | POST /api/users |
| PUT | 全量更新 | 是 | PUT /api/users/123 |
| PATCH | 部分更新 | 是 | PATCH /api/users/123 |
| DELETE | 删除资源 | 是 | DELETE /api/users/123 |
4.2 状态码
| 范围 | 含义 | 常用 |
|---|---|---|
| 2xx | 成功 | 200 OK, 201 Created, 204 No Content |
| 3xx | 重定向 | 301 Moved, 304 Not Modified |
| 4xx | 客户端错误 | 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 429 Too Many Requests |
| 5xx | 服务端错误 | 500 Internal Error, 502 Bad Gateway, 503 Unavailable |
4.3 API 版本化
# URL 路径版本化(最常用)
GET /api/v1/users
GET /api/v2/users
# Header 版本化
GET /api/users
Accept: application/vnd.myapp.v2+json
# Query 参数版本化
GET /api/users?version=2
4.4 分页、过滤、排序
GET /api/users?page=2&per_page=20
GET /api/users?age_gte=18&status=active
GET /api/users?sort=-created_at,name
Response:
{
"data": [...],
"meta": {
"total": 150,
"page": 2,
"per_page": 20,
"pages": 8
}
}
5. 认证与授权
5.1 JWT(JSON Web Token)
Header.Payload.Signature
Header: {"alg": "HS256", "typ": "JWT"}
Payload: {"sub": "user123", "exp": 1700000000, "role": "admin"}
Signature: HMACSHA256(base64(header) + "." + base64(payload), secret)
# FastAPI JWT 示例
from jose import jwt
from datetime import datetime, timedelta
SECRET_KEY = "your-secret-key"
def create_access_token(data: dict, expires_delta: timedelta = timedelta(hours=1)):
to_encode = data.copy()
to_encode["exp"] = datetime.utcnow() + expires_delta
return jwt.encode(to_encode, SECRET_KEY, algorithm="HS256")
def get_current_user(token: str = Depends(oauth2_scheme)):
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
user_id = payload.get("sub")
if user_id is None:
raise HTTPException(status_code=401)
return user_id
except jwt.JWTError:
raise HTTPException(status_code=401)
5.2 OAuth 2.0
用户 → 应用 → 授权服务器(Google/GitHub)
│
▼ 授权码
用户 ← 应用 ← 授权服务器
│
▼ Access Token
资源服务器 → 返回用户数据
四种授权模式:
| 模式 | 适用场景 |
|---|---|
| Authorization Code | Web 应用(最安全) |
| PKCE | 单页应用 / 移动端 |
| Client Credentials | 服务间通信 |
| Device Code | IoT / 无浏览器设备 |
6. 数据库
6.1 SQL(PostgreSQL)
-- 表设计
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE posts (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
title VARCHAR(255) NOT NULL,
content TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_posts_user_id ON posts(user_id);
-- 查询:JOIN + 聚合
SELECT u.name, COUNT(p.id) as post_count
FROM users u
LEFT JOIN posts p ON u.id = p.user_id
GROUP BY u.id, u.name
HAVING COUNT(p.id) > 5
ORDER BY post_count DESC;
6.2 NoSQL(MongoDB)
// 文档模型:灵活的 schema
db.users.insertOne({
name: "Alice",
email: "alice@example.com",
profile: {
bio: "Developer",
skills: ["Python", "React", "MongoDB"]
},
posts: [
{ title: "Hello World", date: ISODate("2024-01-01") }
]
});
// 聚合管道
db.orders.aggregate([
{ $match: { status: "completed" } },
{ $group: { _id: "$user_id", total: { $sum: "$amount" } } },
{ $sort: { total: -1 } },
{ $limit: 10 }
]);
6.3 SQL vs NoSQL
| 维度 | SQL (PostgreSQL) | NoSQL (MongoDB) |
|---|---|---|
| 数据模型 | 关系表 | 文档/键值/图 |
| Schema | 固定(需迁移) | 灵活 |
| 事务 | 完整 ACID | 有限支持 |
| 扩展 | 垂直为主 | 水平为主 |
| 适用 | 复杂查询、数据一致性 | 快速迭代、大规模数据 |
7. 开发工具与实践
| 工具类型 | 推荐 |
|---|---|
| API 测试 | Postman, httpie, curl |
| API 文档 | Swagger/OpenAPI, Redoc |
| 数据库迁移 | Alembic (Python), Flyway (Java) |
| ORM | SQLAlchemy, Django ORM, Prisma |
| 前端构建 | Vite, Webpack, esbuild |
| 全栈框架 | Next.js, Nuxt.js, Django |
与其他主题的关系
- 参见 系统设计,理解 API、缓存、数据库与前后端边界如何形成整体系统
- 参见 数据库系统,理解关系型与 NoSQL 存储如何服务于应用层
- 参见 版本控制与CI/CD,理解全栈项目的构建、测试与发布流程
- 参见 测试与质量保障,理解前端、后端与端到端测试如何配合
参考文献
- React 官方文档:https://react.dev
- Vue 官方文档:https://vuejs.org
- FastAPI 官方文档:https://fastapi.tiangolo.com
- "RESTful Web APIs" - Leonard Richardson