bigywater.tech
Flask · 101

Flask 实现 JSON API

用 Flask 写 JSON API,返回值与请求体各有哪些默认行为?哪些类型能序列化?请求头不对会返回什么?这篇用 test_client 把每种情况的状态码与响应逐个打印出来。

415
Content-Type 不是 application/json 时 get_json() 的状态码
sort_keys
默认为 True,返回的键会被排序
500
视图返回 None 或 set 时的状态码

返回 dict、list 与 jsonify

实测 · 本机执行输出
  return {...}                       → 200 application/json | {"a":"\u4e2d\u6587","b":1,"c":[1,2]}
  return jsonify(...)                → 200 application/json | {"a":"\u4e2d\u6587","b":1}
  return [...](顶层列表)                 → 200 application/json | [1,2,{"x":1}]
  return {...}, 201, {Location}      → 201 application/json | {"id":7}
    Location 头: /items/7
  当前默认值:app.json.sort_keys = True | ensure_ascii = True | compact = None | mimetype = application/json

上一篇:数据库连接断开后的恢复;下一篇:API 错误响应统一格式。

可序列化的类型

实测 · 本机执行输出
  datetime / date / Decimal / UUID   → 200 application/json | {"day":"Fri, 02 Jan 2026 00:00:00 GMT","id":"12345678-1234-5678-1234-567812345678","price":"1.10","when":"Fri,
  set(默认不支持)                         → 500 text/html; charset=utf-8
    状态码 500,响应是 HTML 错误页(不是 JSON)

读取请求体

实测 · 本机执行输出
  Content-Type: application/json + 合法 JSON   → 200 {"got":{"a":1}}
  Content-Type: application/json + 非法 JSON   → 400 <!doctype html> <html lang=en> <title>400 Bad Request</title> <h1>Bad Request</h1> <p>The browse
  Content-Type: text/plain + 合法 JSON         → 415 <!doctype html> <html lang=en> <title>415 Unsupported Media Type</title> <h1>Unsupported Media T
  没有 Content-Type + 合法 JSON                  → 415 <!doctype html> <html lang=en> <title>415 Unsupported Media Type</title> <h1>Unsupported Media T
  application/json + 空请求体                    → 400 <!doctype html> <html lang=en> <title>400 Bad Request</title> <h1>Bad Request</h1> <p>The browse
  silent=True + 非法 JSON → 200 {"got":null}
  force=True + text/plain → 200 {"got":{"a":1}}
  test_client 的 json= 参数 → 200 {"got":{"a":1}}

None 与字符串

实测 · 本机执行输出
  return None                        → 500 text/html; charset=utf-8
     <!doctype html> <html lang=en> <title>500 Internal Server Error</title> <h1>Internal Server Error</h1> <p>The server encountered a
  return "plain"                     → 200 text/html; charset=utf-8 | plain

自定义 JSON provider

实测 · 本机执行输出
   {"b":1,"a":"中文","s":[1,2]}
   (默认 provider 的同一份数据: {"a":"\u4e2d\u6587","b":1,"c":[1,2]} )

序列化的开销

实测 · 本机执行输出
  经 Flask 返回 0.71 ms/次,纯 json.dumps 0.51 ms/次;响应大小 59041 字节

分步演示

JSON API
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Python 3.14.7 / Flask 3.1.3 / Werkzeug 3.1.9 / Jinja2 3.1.6 / SQLAlchemy 2.1.1 / gunicorn 26.2.0(都装在自己的虚拟环境里);大多数实验用 Flask 的 test_client(直接调用 WSGI 应用,不经过网络),需要真实 HTTP 时另起 gunicorn 或开发服务器(端口 9600 以上,本机 127.0.0.1);计时用 time.perf_counter,数字每次运行会有小幅抖动
    • 没有验证:真实 HTTP 下 Content-Length 与分块编码对 get_json 的影响、超大请求体的限制(MAX_CONTENT_LENGTH)、其它 JSON 库(orjson)作为 provider 的效果、JSONP 与 JSON 安全问题
    京ICP备2026067502号-1京公网安备11010502063487号