简体   繁体   中英

Adding CORS header into gqlgen default example?

I'm trying to setup up a basic stack using React, Apollo served by graphQL served by Go through gqlgen.

I'm following the getting started guide for gqlgen, which works fine.

I'm also following the getting started guide for Apollo, which works fine.

My trouble lies in the chrome not allowing me to ping the backend when I try to stitch the two together. I get a CORS preflight header error which is understandable, considering React is on localhost:3000 and the Go server is on localhost:8080

gqlgen provided a helpful example on how to get CORS running on the Go server here using chi and go-cors. However the example provided is based of the starwars example of gqlgen rather then the getting-started example.

I modified the CORS example to the following:

package main

import (
    "net/http"

    "github.com/99designs/gqlgen/graphql/handler"
    "github.com/99designs/gqlgen/graphql/handler/transport"
    "github.com/99designs/gqlgen/graphql/playground"
    "github.com/FlockSupport/graphql/graph"
    "github.com/FlockSupport/graphql/graph/generated"
    "github.com/go-chi/chi"
    "github.com/gorilla/websocket"
    "github.com/rs/cors"
)

func main() {
    router := chi.NewRouter()

    // Add CORS middleware around every request
    // See https://github.com/rs/cors for full option listing
    router.Use(cors.New(cors.Options{
        AllowedOrigins:   []string{"http://localhost:8080"},
        AllowCredentials: true,
        Debug:            true,
    }).Handler)

    // srv := handler.New(starwars.NewExecutableSchema(starwars.NewResolver())) // MODIFIED THIS.
    srv := handler.New(generated.NewExecutableSchema(generated.Config{Resolvers: &graph.Resolver{}}))

    srv.AddTransport(&transport.Websocket{
        Upgrader: websocket.Upgrader{
            CheckOrigin: func(r *http.Request) bool {
                // Check against your desired domains here
                return r.Host == "example.org"
            },
            ReadBufferSize:  1024,
            WriteBufferSize: 1024,
        },
    })

    router.Handle("/", playground.Handler("GraphQL Playground", "/query"))
    // router.Handle("/", handler.Playground("Starwars", "/query")) // MODIFIED THIS.
    router.Handle("/query", srv)

    err := http.ListenAndServe(":8080", router)
    if err != nil {
        panic(err)
    }
}

The server runs, but testing queries out through the playground (localhost:8080 so CORS shouldn't matter here) gives the following error:

{
  "error": {
    "errors": [
      {
        "message": "transport not supported"
      }
    ],
    "data": null
  }
}

This also doesn't work even if I setup the Chi router only:


func main() {
    router := chi.NewRouter()

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

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

    err := http.ListenAndServe(":8080", router)
    if err != nil {
        panic(err)
    }
}

I get a Server Cannot Be Reached when I access localhost:8080 playground.

How can I enable CORS properly on the gqlgen Go server so React can ping it?

You need to provide CORS checks as middleware. For instance you could use "github.com/rs/cors". It could looks like following code

mux.Handle("/playground", handler.Playground("API", "/gql"))
mux.Handle("/gql",
    handler.GraphQL(
        gen.NewExecutableSchema(gen.Config{Resolvers: resolver.New(dep)}),
        handler.ErrorPresenter(errorCustomize)))
h := cors.AllowAll().Handler(util.JwtMiddleware(mux))

srv := &http.Server{
    Addr:    ":8087",
    Handler: h,
}

我遇到了同样的问题,并通过使用NewDefaultServer方法而不是New解决了它。

srv := handler.NewDefaultServer(.....)

I had the same problem but actually it was because, when I did the request to the server I didn't add the header Content-Type: application/json . curiously I had to include the Content-Length header when using postman.

so, when I tried:

    curl --request POST \
    --url http://localhost:8000/ \
    --data '{"query":"query {\n  televisions {\n    id\n  }\n}"}'

This was the response:

{"errors":[{"message":"transport not supported"}],"data":null}

But when I added the header:

    curl --request POST \
    --url http://localhost:8000/ \
    --header 'content-type: application/json' \
    --data '{"query":"query {\n  televisions {\n    id\n  }\n}"}'

The server response normally:

{"data":{"televisions":[]}}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM