graphql服务启动失败主因是schema未正确定义query根类型或resolver未挂载:必须显式设置schemaconfig.query为含字段及resolve函数的object,resolver签名须严格匹配func(p graphql.resolveparams) (interface{}, error),且http handler需用graphql-go/handler.new并正确解析post json。

用 graphql-go/graphql 启动服务失败,八成是 schema 没配对 Query 根类型,或 resolver 函数没挂到字段上——它不报错,只静默返回空响应。
schema 必须显式设 Query 字段,不能只塞 Types
很多人写完 User 类型就直接丢进 SchemaConfig.Types,结果请求 200 但 body 是空对象。GraphQL 规范要求必须指定根查询类型,graphql-go 不会 fallback、不自动推导。
-
SchemaConfig.Query必须设为一个graphql.Object,且该 object 至少含一个字段(如hello)和对应Resolve函数 - 别把
Query当普通 type 塞进Types数组里——它得单独拎出来赋值给Query字段 - 如果要用
Mutation,同样要显式设SchemaConfig.Mutation,否则mutation关键字直接被忽略
resolver 函数签名和挂载方式必须严格匹配
graphql-go 的 resolver 不靠反射自动绑定,全靠你手写函数并手动塞进 graphql.Field 的 Resolve 字段。漏一个,那个字段就永远返回 null。
- 每个字段的
Resolve必须是func(p graphql.ResolveParams) (interface{}, error)类型,少一个参数或类型不对,运行时不会报错,但字段值为空 -
p.Source是上层返回值(比如Query返回 struct,User字段的p.Source就是那个 struct),调试时先fmt.Printf("%+v", p.Source)确认数据传下来了 - 字段名大小写必须完全一致:schema 里写
user,resolver 函数就得叫User(首字母大写导出),否则field "user" not defined on type "Query"
HTTP handler 要支持 POST + application/json,不能只靠默认路由
用 http.HandleFunc 直接套 graphql.Handler 会失效——它只解析 URL 查询参数,POST body 里的 JSON 查询会被忽略,返回空响应且无日志。
- 必须用
graphql-go/handler.New替代graphql-go/handler.GraphQL,并设Playground: true和GraphiQL: true - 手动读 body:
body, _ := io.ReadAll(r.Body),再json.Unmarshal到struct { Query, Variables string },然后传给graphql.Params - 别忘了设响应头:
w.Header().Set("Content-Type", "application/json"),否则某些客户端(如 curl)会卡住
resolver 里取 context 和依赖只能靠 p.Info.RootValue
graphql-go 的 resolver 签名固定,没法加额外参数。想传 DB 连接、token、logger,唯一合法出口是 RootValue —— 它是每次请求独享的 interface{},不是全局变量。
- 启动 handler 时,在
graphql.Params里填RootValue: map[string]interface{}{"db": db, "ctx": r.Context()} - resolver 内通过
p.Info.RootValue.(map[string]interface{})["db"]取 DB,注意类型断言要带ok判断,避免 panic - 别把
*sql.DB或log.Logger存进 schema 全局变量——并发下会因非线程安全而崩溃
最常被忽略的是:resolver 返回 nil 时不报错,前端只看到 null;错误没检查 result.HasErrors() 就直接序列化,导致前端收不到任何错误信息。这两处不补,调试成本翻倍。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











