graphqlview 默认禁用 get,需显式传 get=true 且依赖 graphene>=3.0 和 flask-graphql>=3.0.0b1;resolver 中 info 必须在参数末尾并带 graphene.resolveinfo 注解;context 需用 lambda 动态注入 request;弃用已归档的 graphene-flask,改用 flask-graphql + graphene v3。

GraphQLView 默认只接受 POST,开发时用浏览器 GET 访问 /graphql?query={} 会直接 405,必须显式启用 GET 支持。
GraphQLView.as_view() 必须传 get=True 才能响应浏览器 GET 请求
Flask-GraphQL 的 GraphQLView 在 graphene>=3.0 版本中才支持 get=True 参数。旧版(如 graphene==2.x)不识别该参数,调用会静默忽略,仍返回 405。
- 确保安装的是
graphene>=3.2和flask-graphql>=3.0.0b1 app.add_url_rule('/graphql', view_func=GraphQLView.as_view('graphql', schema=schema, graphiql=True, get=True))- 生产环境务必设为
get=False或直接移除该参数,避免敏感查询被代理/CDN 缓存或日志记录
resolve_* 方法参数顺序和类型注解不能错
Graphene v3 要求 info 必须放在 resolver 最后,且带类型注解;否则字段返回 null,无报错,前端只能看到空值。
- 错误写法:
def resolve_hello(self, info, name):→ 静默失效 - 正确写法:
def resolve_hello(self, name, info) -> str:(注意info在末尾 + 类型注解) -
info类型必须是graphene.ResolveInfo,不是Any或省略 - 字段声明为
graphene.String()时,resolver 绝对不能返回None,否则抛Cannot return null for non-nullable field
info.context 必须用 lambda 动态注入 Flask request
context={'request': request} 是错的——它在应用启动时就求值,所有请求共享同一个 request 对象。必须用可调用对象,让每次请求都拿到当前上下文。
- 正确写法:
context=lambda: {'request': request} - 在 resolver 中取:
auth = info.context['request'].headers.get('Authorization') - 别在
context里传数据库连接等需 per-request 初始化的对象,应放info.context再由 resolver 按需创建
别用已归档的 graphene-flask,改用 flask-graphql + graphene v3
graphene-flask 自 2021 年起停止维护,最新版只兼容 Flask 1.x,与当前主流 Flask 2.3+ / 3.x 不兼容,会报 AttributeError: 'Flask' object has no attribute 'add_url_rule' 或找不到执行器。
- 弃用:
pip uninstall graphene-flask - 改用:
pip install flask-graphql graphene>=3.2 -
flask-graphql只做 HTTP 层胶水,Schema 层仍用graphene,迁移成本低 - 如果需要异步支持(比如 await DB 查询),
graphene原生不支持,得换ariadne或手动 wrapasyncio.run()(不推荐)
query 参数必须 URL-decoded,variables 和 operationName 也得从 request.args 手动解析并 json.loads() ——漏掉这步,变量传进去是字符串,GraphQL 引擎会报 “Cannot query field” 这类误导性错误。Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











