Graphql Subscriptions not working with Gin

Viewed 559

When I tried to setup a Go web server with GraphQL I used this as template. It is basically a combo of gin and 99designs/gqlgen.

When I create a basic gqlgen server based on net/http package, the declaration of GraphQL subscriptions work as expected.

package main

import (
    "log"
    "net/http"
    "os"

    "github.com/99designs/gqlgen/graphql/handler"
    "github.com/99designs/gqlgen/graphql/playground"
    "github.com/jawil003/gqlgen/graph"
    "github.com/jawil003/gqlgen/graph/generated"
)

const defaultPort = "8080"

func main() {
    port := os.Getenv("PORT")
    if port == "" {
        port = defaultPort
    }

    srv := handler.NewDefaultServer(generated.NewExecutableSchema(generated.Config{Resolvers: &graph.Resolver{}}))

    http.Handle("/", playground.Handler("GraphQL playground", "/query"))
    http.Handle("/query", srv)

    log.Printf("connect to http://localhost:%s/ for GraphQL playground", port)
    log.Fatal(http.ListenAndServe(":"+port, nil))
}

But when I add gin, like this:

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"
)

// Defining the Graphql handler
func graphqlHandler() gin.HandlerFunc {
    // NewExecutableSchema and Config are in the generated.go file
    // Resolver is in the resolver.go file
    h := handler.NewDefaultServer(generated.NewExecutableSchema(generated.Config{Resolvers: &graph.Resolver{}}))

    return func(c *gin.Context) {
        h.ServeHTTP(c.Writer, c.Request)
    }
}

// Defining the Playground handler
func playgroundHandler() gin.HandlerFunc {
    h := playground.Handler("GraphQL", "/query")

    return func(c *gin.Context) {
        h.ServeHTTP(c.Writer, c.Request)
    }
}

func main() {
    // Setting up Gin
    r := gin.Default()
    r.POST("/query", graphqlHandler())
    r.GET("/", playgroundHandler())
    r.Run()
}

I get this issue:

{ "error": "Could not connect to websocket endpoint ws://localhost:8080/query. Please check if the endpoint url is correct." }

Is there any known solution to make gin work with graphql subscriptions?

2 Answers

Hello to fix error Could not connect to websocket endpoint.. with Gin change r.POST("/query", graphqlHandler()) to r.Any("/query", graphqlHandler())

Please for this combination of Gin and Graphql, is it possible to have two different routes? One for the query/mutations and one different one for subscription. As in below:

func main() {
    // Setting up Gin
    r := gin.Default()
    r.POST("/query", graphqlHandler())
    r.POST("/subscription", graphqlHandler())
    r.GET("/", playgroundHandler())
    r.Run()
}
Related