01 - 后端学习路径¶
目标:系统学习后端开发,能独立设计和实现API服务
时间:4-6周
核心原则:理解HTTP、掌握数据库、学会API设计
🎯 后端是什么?¶
后端开发 = 服务器端的逻辑处理和数据管理
📚 学习路径¶
阶段1:HTTP与Web基础(1周)¶
阶段2:数据库(1-2周)¶
阶段3:进阶后端(2-3周)¶
🛠️ 技术栈选择¶
Python后端技术栈¶
Text Only
Web框架:
- FastAPI(推荐,现代、高性能)
- Flask(轻量、灵活)
- Django(全功能、适合大型项目)
数据库:
- PostgreSQL(推荐,功能强大)
- MySQL(广泛使用)
- SQLite(开发测试)
ORM:
- SQLAlchemy(功能全面)
- Tortoise ORM(异步支持好)
缓存:
- Redis(必备)
其他:
- Docker(部署)
- Nginx(反向代理)
📖 详细学习内容¶
Week 1: HTTP与Web基础¶
HTTP协议¶
Text Only
HTTP请求:
GET /users HTTP/1.1
Host: api.example.com
Authorization: Bearer token123
HTTP响应:
HTTP/1.1 200 OK
Content-Type: application/json
{
"users": [
{"id": 1, "name": "Alice"},
{"id": 2, "name": "Bob"}
]
}
HTTP方法: - GET:获取资源 - POST:创建资源 - PUT:更新资源(完整) - PATCH:更新资源(部分) - DELETE:删除资源
HTTP状态码: - 200 OK:成功 - 201 Created:创建成功 - 400 Bad Request:请求参数错误 - 401 Unauthorized:未认证 - 403 Forbidden:无权限 - 404 Not Found:资源不存在 - 500 Internal Server Error:服务器错误
RESTful API设计¶
Text Only
资源:用户(User)
GET /users # 获取所有用户
GET /users/1 # 获取ID为1的用户
POST /users # 创建用户
PUT /users/1 # 更新ID为1的用户
DELETE /users/1 # 删除ID为1的用户
资源:文章(Post)
GET /posts # 获取所有文章
GET /posts/1 # 获取ID为1的文章
GET /users/1/posts # 获取用户1的所有文章
POST /users/1/posts # 为用户1创建文章
FastAPI入门¶
Python
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel # Pydantic数据验证模型
app = FastAPI()
# 数据模型
class User(BaseModel):
id: int
name: str
email: str
# 模拟数据库
users = {}
# 获取所有用户
@app.get("/users")
def get_users():
return list(users.values())
# 获取单个用户
@app.get("/users/{user_id}")
def get_user(user_id: int):
if user_id not in users:
raise HTTPException(status_code=404, detail="User not found")
return users[user_id]
# 创建用户
@app.post("/users", status_code=201)
def create_user(user: User):
if user.id in users:
raise HTTPException(status_code=400, detail="User already exists")
users[user.id] = user
return user
# 更新用户
@app.put("/users/{user_id}")
def update_user(user_id: int, user: User):
if user_id not in users:
raise HTTPException(status_code=404, detail="User not found")
users[user_id] = user
return user
# 删除用户
@app.delete("/users/{user_id}")
def delete_user(user_id: int):
if user_id not in users:
raise HTTPException(status_code=404, detail="User not found")
del users[user_id]
return {"message": "User deleted"}
# 运行
# uvicorn main:app --reload
Week 2-3: 数据库¶
SQL基础¶
SQL
-- 创建表
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 插入数据
INSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com');
-- 查询数据
SELECT * FROM users WHERE id = 1;
SELECT * FROM users ORDER BY created_at DESC LIMIT 10;
-- 更新数据
UPDATE users SET name = 'Bob' WHERE id = 1;
-- 删除数据
DELETE FROM users WHERE id = 1;
-- 关联查询
SELECT posts.title, users.name
FROM posts
JOIN users ON posts.user_id = users.id; -- JOIN连接多个表
SQLAlchemy ORM¶
Python
from sqlalchemy import create_engine, Column, Integer, String, DateTime, ForeignKey
from sqlalchemy.orm import sessionmaker, relationship, declarative_base
from datetime import datetime, timezone
Base = declarative_base()
# 定义模型
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String(100), nullable=False)
email = Column(String(100), unique=True, nullable=False)
created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc)) # lambda匿名函数:简洁的单行函数
# 关系
posts = relationship("Post", back_populates="author")
class Post(Base):
__tablename__ = 'posts'
id = Column(Integer, primary_key=True)
title = Column(String(200), nullable=False)
content = Column(String, nullable=False)
user_id = Column(Integer, ForeignKey('users.id'))
created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
# 关系
author = relationship("User", back_populates="posts")
# 连接数据库(SQLAlchemy 2.0 风格)
engine = create_engine('postgresql://user:password@localhost/dbname')
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
# CRUD操作(SQLAlchemy 2.0 推荐使用 session.execute + select)
from sqlalchemy import select
def create_user(name, email):
with Session() as session:
user = User(name=name, email=email)
session.add(user)
session.commit()
session.refresh(user)
return user
def get_user(user_id):
with Session() as session:
# SQLAlchemy 2.0 风格(替代旧的 session.query(User).filter(...))
user = session.execute(
select(User).where(User.id == user_id)
).scalar_one_or_none()
return user
def get_all_users():
with Session() as session:
# SQLAlchemy 2.0 风格(替代旧的 session.query(User).all())
users = session.execute(select(User)).scalars().all()
return users
数据库设计原则¶
Text Only
1. 范式化
- 第一范式:每个字段原子性
- 第二范式:非主键字段完全依赖主键
- 第三范式:消除传递依赖
2. 索引优化
- 主键自动创建索引
- 外键创建索引
- 经常查询的字段创建索引
3. 关系设计
- 一对一:用户-用户详情
- 一对多:用户-文章
- 多对多:文章-标签(需要中间表)
Week 4-5: 进阶后端¶
用户认证(JWT)¶
Python
from fastapi import Depends, HTTPException, status
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
import jwt
from datetime import datetime, timedelta, timezone
SECRET_KEY = "your-secret-key"
ALGORITHM = "HS256"
# 创建JWT令牌
def create_access_token(data: dict, expires_delta: timedelta = None):
to_encode = data.copy()
if expires_delta:
expire = datetime.now(timezone.utc) + expires_delta
else:
expire = datetime.now(timezone.utc) + timedelta(minutes=15)
to_encode.update({"exp": expire})
encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
return encoded_jwt
# 验证JWT令牌
security = HTTPBearer()
def get_current_user(credentials: HTTPAuthorizationCredentials = Depends(security)):
token = credentials.credentials
try: # try/except捕获异常
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
user_id = payload.get("sub")
if user_id is None:
raise HTTPException(status_code=401, detail="Invalid token")
return get_user(int(user_id))
except jwt.ExpiredSignatureError:
raise HTTPException(status_code=401, detail="Token expired")
except jwt.JWTError:
raise HTTPException(status_code=401, detail="Invalid token")
# 使用认证
@app.get("/me")
def read_current_user(current_user: User = Depends(get_current_user)):
return current_user
日志和错误处理¶
Python
import logging
from fastapi import Request
from fastapi.responses import JSONResponse
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('app.log'),
logging.StreamHandler()
]
)
logger = logging.getLogger(__name__)
# 全局异常处理
@app.exception_handler(Exception)
async def global_exception_handler(request: Request, exc: Exception): # async def定义异步函数;用await调用
logger.error(f"Error: {exc}", exc_info=True)
return JSONResponse(
status_code=500,
content={"message": "Internal server error"}
)
# 请求日志中间件
@app.middleware("http")
async def log_requests(request: Request, call_next):
logger.info(f"Request: {request.method} {request.url}")
response = await call_next(request) # await等待异步操作完成
logger.info(f"Response: {response.status_code}")
return response
测试¶
Python
from fastapi.testclient import TestClient
import pytest
client = TestClient(app)
def test_get_users():
response = client.get("/users")
assert response.status_code == 200 # assert断言:条件为False时抛出AssertionError
assert isinstance(response.json(), list) # isinstance检查对象类型
def test_create_user():
user_data = {
"id": 1,
"name": "Test User",
"email": "test@example.com"
}
response = client.post("/users", json=user_data)
assert response.status_code == 201
assert response.json()["name"] == "Test User"
def test_get_user_not_found():
response = client.get("/users/999")
assert response.status_code == 404
🎯 学习检查点¶
Week 1结束后:¶
- 理解HTTP协议和RESTful设计
- 能用FastAPI创建简单API
- 能处理CRUD操作
Week 2-3结束后:¶
- 掌握SQL基础
- 能用ORM操作数据库
- 能设计合理的数据库结构
Week 4-5结束后:¶
- 能实现用户认证
- 能处理错误和日志
- 能编写API测试
Week 6结束后:¶
- 完成完整的后端项目
- 能部署到云服务器
📚 推荐资源¶
在线教程¶
- FastAPI官方文档(有中文)
- SQLAlchemy教程
- PostgreSQL官方文档
书籍¶
- 《Flask Web开发》
- 《高性能MySQL》
- 《设计数据密集型应用》
练习平台¶
- Postman(API测试)
- LeetCode(数据库题)
- HackerRank(SQL练习)
🚀 下一步¶
完成后端基础学习后,可结合 06-系统设计与架构/01-系统设计原则.md 提升架构设计能力!
记住:后端是应用的基石,稳定的后端是产品成功的保障! 🏗️