使用 Claude Code 构建 RESTful API
🎯 RESTful API 基础
RESTful API 是现代Web应用的核心。使用 Claude Code,你可以:
- 快速生成代码:自动生成路由、控制器、模型
- 遵循最佳实践:代码符合REST规范和安全标准
- 自动化文档:生成API文档和测试用例
- 错误处理:完善的异常处理和错误响应
RESTful API 核心原则:
- 资源导向:一切皆资源(用户、文章、商品等)
- HTTP 方法:GET(获取)、POST(创建)、PUT(更新)、DELETE(删除)
- 无状态:每个请求包含所有必要信息
- 统一接口:一致的URL结构和响应格式
🛠️ 选择合适的框架
Python 框架对比
让 Claude 帮你选择框架:
你:我要开发一个用户管理API,应该选择哪个Python框架? Claude 的建议: 1. **FastAPI** (推荐) 优点: - 现代化、性能优异 - 自动生成API文档(Swagger UI) - 类型提示和数据验证 - 异步支持 适用场景:新项目、高性能需求、需要自动文档 2. **Flask** 优点: - 轻量级、灵活 - 生态系统成熟 - 学习曲线平缓 适用场景:简单API、快速原型、完全控制 3. **Django REST Framework** 优点: - 功能全面 - 内置ORM和管理后台 - 企业级特性 适用场景:大型项目、需要管理后台、数据库操作多 本教程使用 FastAPI 演示
🚀 项目初始化
1. 让 Claude 创建项目结构
提示词:
你:帮我创建一个FastAPI项目结构,用于用户管理系统 Claude 生成: project/ ├── app/ │ ├── __init__.py │ ├── main.py # 应用入口 │ ├── models.py # 数据模型 │ ├── schemas.py # Pydantic模式 │ ├── crud.py # 数据库操作 │ ├── database.py # 数据库配置 │ └── routers/ │ ├── __init__.py │ └── users.py # 用户路由 ├── tests/ │ ├── __init__.py │ └── test_users.py ├── requirements.txt ├── .env └── README.md
2. 安装依赖
requirements.txt:
fastapi==0.104.1 uvicorn[standard]==0.24.0 sqlalchemy==2.0.23 pydantic==2.5.0 python-jose[cryptography]==3.3.0 passlib[bcrypt]==1.7.4 python-multipart==0.0.6 pytest==7.4.3 httpx==0.25.2
📝 构建 API 端点
1. 定义数据模型
让 Claude 生成模型代码:
你:创建用户模型,包含ID、用户名、邮箱、密码哈希、创建时间
# models.py
from sqlalchemy import Column, Integer, String, DateTime
from sqlalchemy.sql import func
from .database import Base
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
username = Column(String, unique=True, index=True, nullable=False)
email = Column(String, unique=True, index=True, nullable=False)
hashed_password = Column(String, nullable=False)
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
2. 创建 Pydantic Schema
schemas.py:
from pydantic import BaseModel, EmailStr
from datetime import datetime
from typing import Optional
class UserBase(BaseModel):
username: str
email: EmailStr
class UserCreate(UserBase):
password: str
class UserUpdate(BaseModel):
username: Optional[str] = None
email: Optional[EmailStr] = None
password: Optional[str] = None
class UserResponse(UserBase):
id: int
created_at: datetime
class Config:
from_attributes = True
3. 实现 CRUD 操作
让 Claude 生成 CRUD 函数:
# crud.py
from sqlalchemy.orm import Session
from . import models, schemas
from passlib.context import CryptContext
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
def get_user(db: Session, user_id: int):
return db.query(models.User).filter(models.User.id == user_id).first()
def get_user_by_email(db: Session, email: str):
return db.query(models.User).filter(models.User.email == email).first()
def get_users(db: Session, skip: int = 0, limit: int = 100):
return db.query(models.User).offset(skip).limit(limit).all()
def create_user(db: Session, user: schemas.UserCreate):
hashed_password = pwd_context.hash(user.password)
db_user = models.User(
username=user.username,
email=user.email,
hashed_password=hashed_password
)
db.add(db_user)
db.commit()
db.refresh(db_user)
return db_user
def update_user(db: Session, user_id: int, user: schemas.UserUpdate):
db_user = get_user(db, user_id)
if not db_user:
return None
update_data = user.model_dump(exclude_unset=True)
if "password" in update_data:
update_data["hashed_password"] = pwd_context.hash(update_data.pop("password"))
for field, value in update_data.items():
setattr(db_user, field, value)
db.commit()
db.refresh(db_user)
return db_user
def delete_user(db: Session, user_id: int):
db_user = get_user(db, user_id)
if db_user:
db.delete(db_user)
db.commit()
return True
return False
4. 创建 API 路由
routers/users.py:
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from typing import List
from .. import crud, schemas
from ..database import get_db
router = APIRouter(prefix="/users", tags=["users"])
@router.post("/", response_model=schemas.UserResponse, status_code=status.HTTP_201_CREATED)
def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):
"""创建新用户"""
db_user = crud.get_user_by_email(db, email=user.email)
if db_user:
raise HTTPException(
status_code=400,
detail="Email already registered"
)
return crud.create_user(db=db, user=user)
@router.get("/", response_model=List[schemas.UserResponse])
def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
"""获取用户列表"""
users = crud.get_users(db, skip=skip, limit=limit)
return users
@router.get("/{user_id}", response_model=schemas.UserResponse)
def read_user(user_id: int, db: Session = Depends(get_db)):
"""获取单个用户"""
db_user = crud.get_user(db, user_id=user_id)
if db_user is None:
raise HTTPException(status_code=404, detail="User not found")
return db_user
@router.put("/{user_id}", response_model=schemas.UserResponse)
def update_user(user_id: int, user: schemas.UserUpdate, db: Session = Depends(get_db)):
"""更新用户信息"""
db_user = crud.update_user(db, user_id=user_id, user=user)
if db_user is None:
raise HTTPException(status_code=404, detail="User not found")
return db_user
@router.delete("/{user_id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_user(user_id: int, db: Session = Depends(get_db)):
"""删除用户"""
success = crud.delete_user(db, user_id=user_id)
if not success:
raise HTTPException(status_code=404, detail="User not found")
return None
🔐 身份验证
实现 JWT 认证
让 Claude 添加认证功能:
你:为API添加JWT认证
# auth.py
from datetime import datetime, timedelta
from jose import JWTError, jwt
from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from sqlalchemy.orm import Session
SECRET_KEY = "your-secret-key-here" # 应该从环境变量读取
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
def create_access_token(data: dict):
to_encode = data.copy()
expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
to_encode.update({"exp": expire})
encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
return encoded_jwt
def get_current_user(token: str = Depends(oauth2_scheme), db: Session = Depends(get_db)):
credentials_exception = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
headers={"WWW-Authenticate": "Bearer"},
)
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
user_id: int = payload.get("sub")
if user_id is None:
raise credentials_exception
except JWTError:
raise credentials_exception
user = crud.get_user(db, user_id=user_id)
if user is None:
raise credentials_exception
return user
🧪 API 测试
让 Claude 生成测试用例:
# tests/test_users.py
from fastapi.testclient import TestClient
from app.main import app
client = TestClient(app)
def test_create_user():
response = client.post(
"/users/",
json={
"username": "testuser",
"email": "test@example.com",
"password": "testpass123"
}
)
assert response.status_code == 201
data = response.json()
assert data["username"] == "testuser"
assert data["email"] == "test@example.com"
assert "id" in data
def test_read_users():
response = client.get("/users/")
assert response.status_code == 200
assert isinstance(response.json(), list)
def test_read_user():
# 先创建用户
create_response = client.post(
"/users/",
json={
"username": "testuser2",
"email": "test2@example.com",
"password": "testpass123"
}
)
user_id = create_response.json()["id"]
# 读取用户
response = client.get(f"/users/{user_id}")
assert response.status_code == 200
data = response.json()
assert data["id"] == user_id
def test_user_not_found():
response = client.get("/users/99999")
assert response.status_code == 404
🚀 部署上线
部署选项:
- Docker:容器化部署,一致的运行环境
- 云平台:AWS, Azure, Google Cloud
- Vercel/Railway:快速部署Python应用
- 自建服务器:使用Nginx + Gunicorn/Uvicorn
Dockerfile 示例:
FROM python:3.11-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]