Gin集成99designs/gqlgen时GraphQL Subscriptions无法正常工作如何解决?
问题原因
你遇到的WebSocket连接失败是因为gin路由配置限制了/query端点仅支持POST请求,而GraphQL订阅依赖WebSocket协议,需要先发送GET请求完成握手升级,请求被gin拦截返回404,导致连接建立失败。
可行解决方案
1. 修改路由支持必需的请求方法
把原来仅绑定POST方法的/query路由,调整为同时支持POST(普通查询/突变请求)和GET(WebSocket握手请求),两种实现方式二选一即可:
- 直接允许所有请求方法,配置最简单:
把r.POST("/query", graphqlHandler())替换为r.Any("/query", graphqlHandler()) - 仅开放必需的两种方法,安全性更高:
新增GET方法的路由绑定:r.GET("/query", graphqlHandler()) r.POST("/query", graphqlHandler())
2. (可选)适配跨域场景的CORS配置
如果服务需要支持跨域调用,需要在gin的CORS中间件中新增WebSocket相关的允许头:
import "github.com/gin-contrib/cors" r.Use(cors.New(cors.Config{ AllowOrigins: []string{"*"}, // 可按需替换为允许的业务域名 AllowMethods: []string{"GET", "POST", "OPTIONS"}, AllowHeaders: []string{"Content-Type", "Upgrade", "Connection"}, ExposeHeaders: []string{"Content-Length"}, AllowCredentials: true, }))
修正后完整可运行代码示例
package main import ( "github.com/gin-gonic/gin" "github.com/jawil003/gqlgen-todos/graph" "github.com/jawil003/gqlgen-todos/graph/generated" "github.com/99designs/gqlgen/graphql/handler" "github.com/99designs/gqlgen/graphql/playground" ) // Graphql handler func graphqlHandler() gin.HandlerFunc { h := handler.NewDefaultServer(generated.NewExecutableSchema(generated.Config{Resolvers: &graph.Resolver{}})) return func(c *gin.Context) { h.ServeHTTP(c.Writer, c.Request) } } // Playground handler func playgroundHandler() gin.HandlerFunc { h := playground.Handler("GraphQL", "/query") return func(c *gin.Context) { h.ServeHTTP(c.Writer, c.Request) } } func main() { r := gin.Default() // 核心修改:支持GET和POST两种请求方法 r.Any("/query", graphqlHandler()) r.GET("/", playgroundHandler()) r.Run() }
内容的提问来源于stack exchange,提问作者Willey3x37
相关产品推荐
相关产品推荐

