1

I have a private GrapgQL API and I want to write a small public GrapgQL API to consum a few queries/mutations of private API.

From my public resolver give a query to private GrapgQL API, I would like to take the query and its fields, parameters and variables in string in order to then use with my client like github.com/machinebox/graphql

The approach that seems to me to hold the road is to take the RawQuery and pass it on to a GraphQL client. That's why i wrote a middleware to receive the body http, the problem is that I receive all the queries and mutations from the playground like :

query listTodos {
  todos {
    id
    text
  }
}

mutation createTodo {
  createTodo(input:{text: "new todo", userId: "123"}) {
    id
    text
  }
}

In my case, if I have an operationName equal to todos then I would like to see uniquely :

query listTodos {
  todos {
    id
    text
  }
}

Sample (init) :

// server.go
package main

import (
    "bytes"
    "encoding/json"
    "io"
    "log"
    "net/http"
    "os"

    "squirrel/lab/stack-gql/graph"
    "squirrel/lab/stack-gql/graph/generated"

    "github.com/99designs/gqlgen/graphql/handler"
    "github.com/99designs/gqlgen/graphql/playground"
    "github.com/go-chi/chi"
)

const defaultPort = "8081"

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

    router := chi.NewRouter()

    router.Use(middlewareQuery())

    srv := handler.NewDefaultServer(generated.NewExecutableSchema(generated.Config{Resolvers: &graph.Resolver{}}))
    router.Handle("/", playground.Handler("GraphQL playground", "/query"))
    router.Handle("/query", srv)

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

func middlewareQuery() func(http.Handler) http.Handler {
    type bodyGraphQL struct {
        OperationName string   `json:"operationName"`
        Variables     struct{} `json:"variables"`
        Query         string   `json:"query"`
    }

    return func(next http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            buf, err := io.ReadAll(r.Body)
            if err != nil {
                next.ServeHTTP(w, r)
                return
            }

            rdr := io.NopCloser(bytes.NewBuffer(buf))
            r.Body = io.NopCloser(bytes.NewBuffer(buf))

            var body bodyGraphQL

            if err := json.Unmarshal(func(reader io.Reader) []byte {
                buf := new(bytes.Buffer)
                buf.ReadFrom(reader)
                return buf.Bytes()
            }(rdr), &body); err != nil {
                next.ServeHTTP(w, r)
                return
            }

            log.Println(body.Query) // <--- HERE WE WANT TO GET THE QUERY, BUT ONLY THE QUERY NOT ALL PLAYGROUND

            next.ServeHTTP(w, r)
        })
    }
}

eclaude
  • 846
  • 14
  • 30

0 Answers0