跳转至

01 - 后端学习路径

目标:系统学习后端开发,能独立设计和实现API服务

时间:4-6周

核心原则:理解HTTP、掌握数据库、学会API设计


🎯 后端是什么?

后端开发 = 服务器端的逻辑处理和数据管理

Text Only
用户请求 → 后端服务器 → 处理逻辑 → 操作数据库 → 返回数据

你的代码:
- 接收HTTP请求
- 验证和处理数据
- 操作数据库
- 返回JSON响应

📚 学习路径

阶段1:HTTP与Web基础(1周)

Text Only
Week 1:
    - HTTP协议详解
    - RESTful API设计
    - 使用Flask/FastAPI创建简单API
小项目:简单的用户管理系统API

阶段2:数据库(1-2周)

Text Only
Week 2-3:
    - SQL基础(MySQL/PostgreSQL)
    - 数据库设计
    - ORM使用(SQLAlchemy)
    - Redis缓存
小项目:博客系统数据库设计

阶段3:进阶后端(2-3周)

Text Only
Week 4-5:
    - 用户认证(JWT)
    - 权限管理
    - 日志和监控
    - 测试和部署
Week 6:
    - 完整项目实战
    - 部署到云服务器

🛠️ 技术栈选择

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 提升架构设计能力!


记住:后端是应用的基石,稳定的后端是产品成功的保障! 🏗️