Flask API开发:JSON数据返回与状态码设置

在Web开发中,尤其是前后端分离的架构里,API(应用程序接口)是数据交换的核心。Flask作为轻量级Python Web框架,凭借其简洁的特性,常被用于快速开发API。本文将重点讲解如何在Flask中返回JSON格式数据,并正确设置HTTP状态码,帮助初学者理解API开发的基础要点。

一、为什么需要返回JSON?

当我们开发API时,前后端之间需要交换结构化数据。JSON(JavaScript Object Notation)是最常用的数据格式,它轻量、易解析,且与大多数编程语言兼容。例如,前端可以轻松将JSON数据转换为JavaScript对象,后端也能通过JSON解析器处理数据。

二、在Flask中返回JSON数据

Flask提供了专门的工具来处理JSON数据——jsonify函数。它不仅能将Python字典/列表转换为JSON格式,还会自动设置响应头Content-Type: application/json,确保前端能正确识别数据类型。

1. 基本使用示例

首先安装Flask(若未安装):

pip install flask

创建一个简单的Flask应用,返回JSON数据:

from flask import Flask, jsonify

app = Flask(__name__)

# 定义路由,返回JSON数据
@app.route('/greet')
def greet():
    # 构造Python字典(键值对)
    response_data = {
        "message": "Hello, Flask API!",
        "status": "success",
        "code": 200
    }
    # 使用jsonify返回JSON
    return jsonify(response_data)

运行测试:启动Flask应用,访问http://localhost:5000/greet,你会看到类似以下的JSON响应:

{
  "message": "Hello, Flask API!",
  "status": "success",
  "code": 200
}

2. 直接返回字典的误区

注意:如果直接返回Python字典(而非jsonify),Flask会自动处理为JSON吗?
答案是:可以,但不推荐。例如:

@app.route('/test')
def test():
    data = {"name": "Alice", "age": 20}
    return data  # Flask会自动转为JSON,但可能依赖版本或场景

虽然这种方式在多数情况下可行,但jsonify更明确,且能处理非字典类型(如列表、元组),因此建议始终使用jsonify

三、HTTP状态码的作用

HTTP状态码是服务器返回给客户端的“结果报告”,帮助前端(或调用方)判断请求是否成功。例如:
- 200 OK:请求成功(最常用);
- 201 Created:资源创建成功(常用于POST请求);
- 400 Bad Request:请求参数错误;
- 404 Not Found:资源不存在;
- 500 Internal Server Error:服务器内部错误。

四、在Flask中设置状态码

Flask支持两种方式设置状态码:返回元组使用make_response构造响应对象

1. 返回元组(数据 + 状态码)

在视图函数中,直接返回元组(响应数据, 状态码)即可。例如:

@app.route('/user/<int:user_id>')
def get_user(user_id):
    # 模拟数据(实际中可能从数据库获取)
    user = {"id": user_id, "name": "Bob"}
    # 返回JSON数据 + 状态码200(成功)
    return jsonify(user), 200

@app.route('/user/<int:user_id>')
def get_user(user_id):
    if user_id == 0:
        # 返回错误信息 + 状态码404(资源不存在)
        return jsonify({"error": "User not found"}), 404
    user = {"id": user_id, "name": "Bob"}
    return jsonify(user), 200

2. 使用make_response构造响应对象

对于需要更复杂设置(如自定义响应头)的场景,可先用make_response创建响应对象,再设置状态码:

from flask import make_response

@app.route('/login')
def login():
    # 模拟登录失败
    response = jsonify({"error": "Invalid password"})
    response.status_code = 401  # 设置状态码为“未授权”
    return response

五、常见场景示例

以下是API开发中最常用的场景及对应的JSON返回和状态码设置:

场景1:成功返回数据(GET请求)

需求:获取产品列表
代码

from flask import Flask, jsonify

app = Flask(__name__)

# 模拟产品数据
products = [
    {"id": 1, "name": "Laptop", "price": 999},
    {"id": 2, "name": "Phone", "price": 499}
]

@app.route('/products', methods=['GET'])
def get_products():
    return jsonify({
        "status": "success",
        "data": products
    }), 200  # 200 OK(默认状态码,可省略)

场景2:资源创建成功(POST请求)

需求:创建新用户
代码

from flask import Flask, jsonify, request  # 导入request处理请求数据

app = Flask(__name__)
users = {}  # 模拟数据库

@app.route('/users', methods=['POST'])
def create_user():
    # 获取前端提交的JSON数据
    new_user = request.get_json()
    if not new_user or 'name' not in new_user:
        # 参数错误,返回400
        return jsonify({"error": "Name is required"}), 400

    user_id = len(users) + 1
    users[user_id] = new_user
    # 返回新创建的用户数据 + 201状态码(Created)
    return jsonify({
        "status": "success",
        "data": users[user_id],
        "user_id": user_id
    }), 201

场景3:资源不存在(404错误)

需求:查询不存在的用户
代码

@app.route('/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
    if user_id not in users:
        # 资源不存在,返回404
        return jsonify({"error": f"User {user_id} not found"}), 404
    return jsonify(users[user_id]), 200

场景4:服务器内部错误(500错误)

需求:模拟服务器异常
代码

@app.route('/error')
def trigger_error():
    try:
        # 故意制造错误(如除零)
        1 / 0
    except:
        # 返回错误信息 + 500状态码
        return jsonify({"error": "Server internal error"}), 500

六、总结

  • 返回JSON:始终使用jsonify函数,确保数据格式正确且前端能解析。
  • 状态码设置:通过元组(jsonify(data), status_code)make_response设置,明确请求结果(成功/失败)。
  • 常见状态码200(成功)、201(创建成功)、400(参数错误)、404(资源不存在)、500(服务器错误)。

掌握这些基础后,你就能开发出规范、清晰的Flask API,实现前后端数据的顺畅交互。

小夜