用Python构建简易Web API:Flask vs FastAPI对比实战

0 阅读4分钟

摘要:Python做Web API,Flask和FastAPI是最主流的两个选择。本文用同一个需求分别实现,从性能、开发体验、生态等维度做对比,帮你做出正确的技术选型。

需求:一个简单的待办事项API

实现增删改查四个接口:

  • GET /todos — 获取所有待办
  • POST /todos — 创建待办
  • PUT /todos/{id} — 更新待办
  • DELETE /todos/{id} — 删除待办

Flask实现

pip install flask
from flask import Flask, request, jsonify

app = Flask(__name__)

# 内存存储(生产环境用数据库)
todos = {}
next_id = 1

@app.route('/todos', methods=['GET'])
def get_todos():
    return jsonify(list(todos.values()))

@app.route('/todos', methods=['POST'])
def create_todo():
    global next_id
    data = request.get_json()
    
    if not data or 'title' not in data:
        return jsonify({'error': '缺少title字段'}), 400
    
    todo = {
        'id': next_id,
        'title': data['title'],
        'done': False,
    }
    todos[next_id] = todo
    next_id += 1
    return jsonify(todo), 201

@app.route('/todos/<int:todo_id>', methods=['PUT'])
def update_todo(todo_id):
    if todo_id not in todos:
        return jsonify({'error': '未找到'}), 404
    
    data = request.get_json()
    todo = todos[todo_id]
    todo['title'] = data.get('title', todo['title'])
    todo['done'] = data.get('done', todo['done'])
    return jsonify(todo)

@app.route('/todos/<int:todo_id>', methods=['DELETE'])
def delete_todo(todo_id):
    if todo_id not in todos:
        return jsonify({'error': '未找到'}), 404
    
    del todos[todo_id]
    return '', 204

if __name__ == '__main__':
    app.run(debug=True, port=8000)

FastAPI实现

pip install fastapi uvicorn
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import Optional

app = FastAPI(title='待办事项API', version='1.0')

todos = {}
next_id = 1

class TodoCreate(BaseModel):
    title: str

class TodoUpdate(BaseModel):
    title: Optional[str] = None
    done: Optional[bool] = None

class TodoResponse(BaseModel):
    id: int
    title: str
    done: bool

@app.get('/todos', response_model=list[TodoResponse])
def get_todos():
    return list(todos.values())

@app.post('/todos', response_model=TodoResponse, status_code=201)
def create_todo(data: TodoCreate):
    global next_id
    todo = {'id': next_id, 'title': data.title, 'done': False}
    todos[next_id] = todo
    next_id += 1
    return todo

@app.put('/todos/{todo_id}', response_model=TodoResponse)
def update_todo(todo_id: int, data: TodoUpdate):
    if todo_id not in todos:
        raise HTTPException(status_code=404, detail='未找到')
    
    todo = todos[todo_id]
    if data.title is not None:
        todo['title'] = data.title
    if data.done is not None:
        todo['done'] = data.done
    return todo

@app.delete('/todos/{todo_id}', status_code=204)
def delete_todo(todo_id: int):
    if todo_id not in todos:
        raise HTTPException(status_code=404, detail='未找到')
    del todos[todo_id]

# 运行:uvicorn main:app --reload --port 8000

对比分析

1. 参数校验

Flask需要手动校验每个参数:

# Flask:手动校验
data = request.get_json()
if not data or 'title' not in data:
    return jsonify({'error': '缺少title'}), 400
if not isinstance(data['title'], str):
    return jsonify({'error': 'title必须是字符串'}), 400

FastAPI用Pydantic模型自动校验:

# FastAPI:声明即校验
class TodoCreate(BaseModel):
    title: str  # 自动校验类型,缺失时返回422错误

FastAPI在这方面完胜,代码量少一半,错误信息还更友好。

2. API文档

Flask需要额外安装flask-swagger或flasgger:

pip install flasgger

FastAPI自带交互式文档,启动后访问 /docs(Swagger UI)或 /redoc(ReDoc),零配置。

3. 异步支持

Flask 2.0+支持async,但底层仍是WSGI:

# Flask:async支持有限
@app.route('/data')
async def get_data():
    data = await fetch_from_db()  # 可以用,但性能提升有限
    return jsonify(data)

FastAPI原生异步,基于ASGI:

# FastAPI:原生异步
@app.get('/data')
async def get_data():
    data = await fetch_from_db()  # 真正的异步,性能拉满
    return data

4. 性能基准

用wrk做简单压测(GET /todos,100并发):

框架请求/秒平均延迟
Flask + gunicorn~2,80035ms
FastAPI + uvicorn~8,50012ms

FastAPI快约3倍,主要得益于ASGI和Starlette底层。

5. 生态和社区

维度FlaskFastAPI
发布年份20102018
GitHub Stars68k+78k+
第三方扩展极其丰富快速增长
学习资料海量丰富
企业采用广泛快速增长

Flask生态更成熟,几乎任何需求都能找到现成的扩展。FastAPI虽然年轻,但增长势头很猛。

怎么选?

选Flask的场景:

  • 团队熟悉Flask,迁移成本高
  • 需要大量Flask扩展(如Flask-Admin、Flask-Login)
  • 简单的内部工具或原型
  • 需要服务端渲染(Jinja2模板)

选FastAPI的场景:

  • 新项目,没有历史包袱
  • 纯API服务(前后端分离)
  • 需要高性能和异步
  • 重视类型安全和自动文档
  • 微服务架构

我的建议

2026年了,新项目直接上FastAPI。它在开发体验和性能上都有明显优势,生态也已经足够成熟。Flask依然是好框架,但FastAPI代表了Python Web开发的未来方向。

如果你的项目需要服务端渲染,考虑Flask或Django。纯API服务,FastAPI是当前最优解。