28天0基础前端工程师完成Flask接口编写

发布于:2025-07-29 ⋅ 阅读:(12) ⋅ 点赞:(0)

如何28天完成Flask从0到1编写接口供前端调用,这里进行了四个阶段供28天的一个拆解,拆成可落地的 每天任务清单,每一步都给出完整代码、逐行注释,以及“为什么要这么做”的讲解。你只要按顺序复制-粘贴即可跑通。
(假设你在 macOS / Linux / WSL,Python≥3.8 已装好)


🔧 阶段1:环境搭建与基础路由(1-3 天)

Day1 安装 Flask & 跑起最小应用

# 1) 创建干净目录
mkdir flask-api-demo && cd flask-api-demo

# 2) 建虚拟环境(防止污染全局)
python -m venv venv
source venv/bin/activate          # Windows 用 venv\Scripts\activate

# 3) 装包
pip install Flask==2.*            # 14 版本是旧写法,现在写 2.* 即可

Day2 写最小应用 app.py

# app.py
from flask import Flask, jsonify

app = Flask(__name__)

@app.route("/api/hello", methods=["GET"])
def hello():
    """
    浏览器访问 http://127.0.0.1:5000/api/hello
    返回 {"message": "Hello Frontend!"}
    """
    return jsonify({"message": "Hello Frontend!"})

if __name__ == "__main__":
    # debug=True:代码改动自动重启;5000 端口被占用可改成 5001
    app.run(debug=True)

运行:

python app.py
# * Running on http://127.0.0.1:5000

浏览器打开上面地址,看到 JSON 即成功。

讲解

  • @app.route 相当于给函数“贴”了一个 URL。
  • jsonify 会自动加 Content-Type: application/json 头,前端 fetch 直接 response.json() 即可。

🧩 阶段2:请求处理与响应规范(3-7 天)

Day3 安装额外依赖 & 统一响应格式

pip install flask-cors           # 解决跨域

app.py 里继续:

from flask import Flask, jsonify, request
from flask_cors import CORS

app = Flask(__name__)
CORS(app)      # 一行解决跨域

# ---------- 统一响应格式 ----------
def success(data=None, msg="OK"):
    return jsonify({"code": 0, "msg": msg, "data": data}), 200

def fail(msg="Bad Request", code=400):
    return jsonify({"code": code, "msg": msg, "data": None}), code

Day4 GET 参数获取示例

@app.route("/api/sum", methods=["GET"])
def get_sum():
    """
    请求示例:GET /api/sum?a=3&b=7
    返回:{"code":0,"data":10,"msg":"OK"}
    """
    try:
        a = float(request.args.get("a"))
        b = float(request.args.get("b"))
    except (TypeError, ValueError):
        return fail("参数必须是数字", 400)
    return success(a + b)

浏览器直接访问 http://127.0.0.1:5000/api/sum?a=3&b=7 测试。

Day5 POST JSON 获取示例

@app.route("/api/user", methods=["POST"])
def create_user():
    """
    POST /api/user
    body: {"name":"alice","age":20}
    """
    data = request.get_json(silent=True)  # silent=True 防止不是 JSON 时报 400
    if not data:
        return fail("请求体必须是 JSON", 400)

    name = data.get("name")
    age = data.get("age")
    if not name or not isinstance(age, int):
        return fail("name 缺失或 age 不是整数", 400)

    # 假装写库成功
    return success({"id": 123, "name": name, "age": age})

测试:

curl -X POST http://127.0.0.1:5000/api/user \
     -H "Content-Type: application/json" \
     -d '{"name":"alice","age":20}'

Day6 文件上传示例(Excel/图片通用)

import os
UPLOAD_FOLDER = "uploads"
os.makedirs(UPLOAD_FOLDER, exist_ok=True)

@app.route("/api/upload", methods=["POST"])
def upload_file():
    """
    前端 formData.append("file", fileInput.files[0])
    """
    file = request.files.get("file")
    if not file:
        return fail("请选择文件", 400)

    filename = file.filename
    save_path = os.path.join(UPLOAD_FOLDER, filename)
    try:
        file.save(save_path)
    except Exception as e:
        return fail(f"保存失败:{e}", 500)

    return success({"filename": filename, "size": os.path.getsize(save_path)})

测试:

curl -F "file=@test.xlsx" http://127.0.0.1:5000/api/upload

Day7 异常捕获 + 自定义 404 / 500

# 放在所有路由之后
@app.errorhandler(404)
def not_found(e):
    return fail("接口不存在", 404)

@app.errorhandler(500)
def server_error(e):
    return fail("服务器内部错误", 500)

🔁 与前端联调小提示

  • 前端 fetch 时记得加 credentials:"include" 如需携带 cookie。
  • 如果前端端口是 5173(Vite),CORS(app) 已允许所有来源;正式环境可改为 CORS(app, origins=["http://localhost:5173"]).
  • 返回体统一用 {"code":0, "data":..., "msg":"OK"},前端就能封装一个公共响应拦截器。

至此,阶段1+2 的全部知识点已落地。你可以继续在第8天接入数据库(SQLAlchemy),把 create_user 真正写进表。
下面给出「阶段3 + 阶段4」的每日任务清单(从第8天开始)

📦 阶段3:数据持久化(第8天–第14天)

第8天 安装依赖 & 初始化 SQLAlchemy

# 在阶段2的虚拟环境里继续
pip install Flask-SQLAlchemy==3.*  psycopg2-binary   # 如用 PostgreSQL
# 开发阶段先 SQLite

新建 models.py

# models.py
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

class User(db.Model):
    __tablename__ = "users"
    id   = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), nullable=False)
    age  = db.Column(db.Integer)

    # 把 ORM 对象 -> 字典,方便序列化
    def to_dict(self):
        return {"id": self.id, "name": self.name, "age": self.age}

修改 app.py(初始化 & 建表)

from flask import Flask
from models import db

app = Flask(__name__)
# 生产环境换成 postgresql://user:pwd@host/db
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///demo.db"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db.init_app(app)

@app.before_first_request
def create_tables():
    db.create_all()

第9天 把 create_user 写进表

from flask import request, jsonify
from models import db, User
from app import app   # 避免循环导入,实际项目用蓝图

@app.route("/users", methods=["POST"])
def add_user():
    data = request.get_json(silent=True) or {}
    name = data.get("name")
    age  = data.get("age")
    if not name or not isinstance(age, int):
        return jsonify({"error": "name/age 非法"}), 400

    user = User(name=name, age=age)
    db.session.add(user)
    db.session.commit()
    # 201 Created 规范
    return jsonify(user.to_dict()), 201

测试

curl -X POST http://127.0.0.1:5000/users \
     -H "Content-Type: application/json" \
     -d '{"name":"Alice","age":18}'

第10天 查 & 改 & 删

@app.route("/users/<int:user_id>", methods=["GET"])
def get_user(user_id):
    user = User.query.get_or_404(user_id)
    return jsonify(user.to_dict())

@app.route("/users/<int:user_id>", methods=["PUT"])
def update_user(user_id):
    user = User.query.get_or_404(user_id)
    data = request.get_json(silent=True) or {}
    user.name = data.get("name", user.name)
    user.age  = data.get("age", user.age)
    db.session.commit()
    return jsonify(user.to_dict())

@app.route("/users/<int:user_id>", methods=["DELETE"])
def delete_user(user_id):
    user = User.query.get_or_404(user_id)
    db.session.delete(user)
    db.session.commit()
    return "", 204   # No Content

🔑 阶段4:进阶功能与生产部署(第15天–第28天)

第15-16天 Blueprint 模块化

目录结构:

flask-api-demo/
├─ app/
│  ├─ __init__.py
│  ├─ models.py
│  └─ routes/
│     ├─ __init__.py
│     └─ users.py
├─ run.py
└─ requirements.txt

app/__init__.py

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_cors import CORS

db = SQLAlchemy()

def create_app():
    app = Flask(__name__)
    app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///demo.db"
    db.init_app(app)
    CORS(app)

    from app.routes.users import bp as user_bp
    app.register_blueprint(user_bp, url_prefix="/api")

    return app

app/routes/users.py

from flask import Blueprint, request, jsonify
from app.models import User, db

bp = Blueprint("users", __name__)

@bp.route("/users", methods=["POST"])
def add_user():
    ...

@bp.route("/users/<int:user_id>", methods=["GET"])
def get_user(user_id):
    ...

run.py

from app import create_app
app = create_app()

if __name__ == "__main__":
    app.run(debug=True)

第17-18天 JWT 登录保护

pip install Flask-JWT-Extended

app/__init__.py

from flask_jwt_extended import JWTManager
app.config["JWT_SECRET_KEY"] = "dev-secret-change-me"
jwt = JWTManager(app)

app/routes/auth.py

from flask import Blueprint, request, jsonify
from flask_jwt_extended import create_access_token, jwt_required, get_jwt_identity
from werkzeug.security import check_password_hash, generate_password_hash
from app.models import User, db

auth_bp = Blueprint("auth", __name__)

@auth_bp.route("/login", methods=["POST"])
def login():
    data = request.get_json()
    username, pwd = data.get("username"), data.get("password")
    user = User.query.filter_by(name=username).first()
    if not user or not check_password_hash(user.password_hash, pwd):
        return jsonify({"msg": "用户名或密码错误"}), 401
    token = create_access_token(identity=user.id)
    return jsonify(token=token)

@auth_bp.route("/protected", methods=["GET"])
@jwt_required()
def protected():
    uid = get_jwt_identity()
    user = User.query.get(uid)
    return jsonify(user.to_dict())

第19-20天 自动生成 Swagger

pip install flasgger

app/__init__.py

from flasgger import Swagger
Swagger(app)

在路由函数里加 docstring 即可:

@bp.route("/users", methods=["POST"])
def add_user():
    """
    创建用户
    ---
    tags:
      - users
    parameters:
      - in: body
        name: body
        schema:
          type: object
          required:
            - name
            - age
          properties:
            name:
              type: string
            age:
              type: integer
    responses:
      201:
        description: 创建成功
    """
    ...

浏览器访问 http://127.0.0.1:5000/apidocs 即见 Swagger UI。

第21-22天 Gunicorn 本地预演

pip install gunicorn
gunicorn -w 4 -b 0.0.0.0:8000 "app:create_app()"
  • -w 4:4 个 worker,充分利用多核。
  • Flask 自带开发服务器 仅用于调试,Gunicorn 才是生产级 WSGI。

第23-24天 Nginx 反向代理

/etc/nginx/conf.d/flask.conf

server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass         http://127.0.0.1:8000;
        proxy_set_header   Host $host;
        proxy_set_header   X-Real-IP $remote_addr;
    }

    location /static/ {
        alias /var/www/flask/static/;
    }
}

启动:

sudo nginx -t && sudo systemctl reload nginx

第25-26天 Docker 容器化

Dockerfile

FROM python:3.11-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt

COPY . .
ENV FLASK_APP=run.py
CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:8000", "app:create_app()"]

.dockerignore

venv/
__pycache__/
*.db

构建 & 运行:

docker build -t flask-api .
docker run -p 8000:8000 flask-api

第27-28天 CI/CD 与云部署(可选)

  • GitHub Actions → Docker Hub → 云服务器拉取镜像
  • 或使用 Heroku / Render / AWS ECS 一键部署

✅ 交付物

至此,你拥有:

  1. 全功能 RESTful API(CRUD + JWT + Swagger)
  2. 工程化目录(Blueprint)
  3. 可容器化、可云部署的完整脚本

拿这份代码就能直接上线!


网站公告

今日签到

点亮在社区的每一天
去签到