I'm trying to use SuperGraph as a library.
I think I can summarize the problems that a neophyte (GraphQL and Go) like me can have in these three points:
- How to integrate SuperGraph (especially for CRUD) into an existing Go project that does not already use GraphQL
- how to integrate SuperGraph (especially for CRUD) into an existing Go project that already uses GraphQL
- how to perform other actions (call other code/packages) before, during or after SuperGraph operations (the so-called "actions" of Hasura and other similar projects)
#1
For point number 1 I think I have found a good way with this code:
package main
import (
"context"
"database/sql"
"encoding/json"
"net/http"
"github.com/go-chi/render"
"github.com/dosco/super-graph/core"
"github.com/go-chi/chi"
_ "github.com/jackc/pgx/v4/stdlib"
)
type reqBody struct {
Query string `json:"query"`
}
func sgHandler(sg *core.SuperGraph) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// Check to ensure query was provided in the request body
if r.Body == nil {
http.Error(w, "Must provide graphQL query in request body", 400)
return
}
var rBody reqBody
// Decode the request body into rBody
err := json.NewDecoder(r.Body).Decode(&rBody)
if err != nil {
http.Error(w, "Error parsing JSON request body", 400)
}
// Execute graphQL query
ctx := context.WithValue(r.Context(), core.UserIDKey, 3) // whatever
res, err := sg.GraphQL(ctx, rBody.Query, nil)
// check err
// render.JSON comes from the chi/render package and handles
// marshalling to json, automatically escaping HTML and setting
// the Content-Type as application/json.
render.JSON(w, r, res.Data)
}
}
func main() {
dbConn, err := sql.Open("pgx", "DB_URL")
// check err
sg, err := core.NewSuperGraph(nil, dbConn)
// check err
router := chi.NewRouter()
router.Group(func(r chi.Router) {
router.Post("/graphql", sgHandler(sg))
})
server.Start(router)
}
// Some code from https://medium.com/@bradford_hamilton/building-an-api-with-graphql-and-go-9350df5c9356
it works (although now I have to fully understand how SuperGraph works).
-
Do you have any advice to give me?
-
Anything more solid for future scaling?
#2
For point number 2 (How to integrate SuperGraph (especially for CRUD) into an existing Go project that already uses GraphQL) I don't really know how to do, I have an idea that could solve: a chain of middlewares, but I still have to understand well; I'll try to explain myself with an example:
func main() {
// initialization... see #1
router.Group(func(r chi.Router) {
router.Post("/graphql", superGraphOrSecondHandler())
})
}
func superGraphOrSecondHandler() {
// if SuperGraphHandler is
err != nil && err == supergraph.ErrQueryNotFound // I'm just imagining
// I can call the second graphQL handler with
next()
}
-
Is this a good way of doing it in your opinion?
-
Is there a type of error that I can already use for this case (when I can't find the query in the allow list)? Or should I simply check the error string?
#3
For point number 3 (how to perform other actions (call other code/packages) before, during or after SuperGraph operations (the so-called "actions" of Hasura and other similar projects)) I don't really have good ideas. And this is the point that scares me most of all.
I read https://github.com/dosco/super-graph/issues/69. I think @howesteve had a good idea, although this example clarified my doubts.
I thought of something like this:
func httpHandler(w, r) {
...read in json
...validate json
...call core.GraphQL(context, query, validated_json)
// my idea here: check if this just finished query is followed by an "action"/code to call
query_name := core.Name() // https://pkg.go.dev/github.com/dosco/super-graph/core?tab=doc#Name
query_operation := core.Operation() // https://pkg.go.dev/github.com/dosco/super-graph/core?tab=doc#Operation
...checkForActionsAndDo(query_name, query_operation)
...return output to user
}
- Is this a good way of doing it in your opinion? What am I doing wrong?
Aucun commentaire:
Enregistrer un commentaire