Skip to content

Instantly share code, notes, and snippets.

@sogko
Last active November 16, 2020 03:51
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save sogko/7debd336118e5e7c7f65 to your computer and use it in GitHub Desktop.
Save sogko/7debd336118e5e7c7f65 to your computer and use it in GitHub Desktop.
[graphql-go] Mutation example with `graphql-go/handler`
package main
import (
"github.com/graphql-go/graphql"
"github.com/graphql-go/handler"
"net/http"
)
type Todo struct {
ID string `json:"id"`
Text string `json:"text"`
Done bool `json:"done"`
}
func main() {
// define custom GraphQL ObjectType `todoType` for our Golang struct `Todo`
// Note that
// - the fields in our todoType maps with the json tags for the fields in our struct
// - the field type matches the field type in our struct
todoType := graphql.NewObject(graphql.ObjectConfig{
Name: "Todo",
Fields: graphql.Fields{
"id": &graphql.Field{
Type: graphql.String,
},
"text": &graphql.Field{
Type: graphql.String,
},
"done": &graphql.Field{
Type: graphql.Boolean,
},
},
})
// root mutation
rootMutation := graphql.NewObject(graphql.ObjectConfig{
Name: "RootMutation",
Fields: graphql.Fields{
"createTodo": &graphql.Field{
Type: todoType, // the return type for this field
Args: graphql.FieldConfigArgument{
"text": &graphql.ArgumentConfig{
Type: graphql.NewNonNull(graphql.String),
},
},
Resolve: func(params graphql.ResolveParams) interface{} {
// marshall and cast the argument value
text, _ := params.Args["text"].(string)
// perform mutation operation here
// for e.g. create a Todo and save to DB.
newTodo := &Todo{
ID: "id0001",
Text: text,
Done: false,
}
// return the new Todo object that we supposedly save to DB
// Note here that
// - we are returning a `Todo` struct instance here
// - we previously specified the return Type to be `todoType`
// - `Todo` struct maps to `todoType`, as defined in `todoType` ObjectConfig`
return newTodo
},
},
},
})
// root query
// we just define a trivial example here, since root query is required.
rootQuery := graphql.NewObject(graphql.ObjectConfig{
Name: "RootQuery",
Fields: graphql.Fields{
"lastTodo": &graphql.Field{
Type: todoType,
},
},
})
// define schema
schema, err := graphql.NewSchema(graphql.SchemaConfig{
Query: rootQuery,
Mutation: rootMutation,
})
if err != nil {
panic(err)
}
h := handler.New(&handler.Config{
Schema: &schema,
Pretty: true,
})
// serve HTTP
http.Handle("/graphql", h)
http.ListenAndServe(":8080", nil)
// How to make a HTTP request using cUrl
// -------------------------------------
// In `graphql-go-handler`, based on the GET/POST and the Content-Type header, it expects the input params differently.
// This behaviour was ported from `express-graphql`.
//
//
// 1) using GET
// $ curl -g -GET 'http://localhost:8080/graphql?query=mutation+M{newTodo:createTodo(text:"This+is+a+todo+mutation+example"){text+done}}'
//
// 2) using POST + Content-Type: application/graphql
// $ curl -XPOST http://localhost:8080/graphql -H 'Content-Type: application/graphql' -d 'mutation M { newTodo: createTodo(text: "This is a todo mutation example") { text done } }'
//
// 3) using POST + Content-Type: application/json
// $ curl -XPOST http://localhost:8080/graphql -H 'Content-Type: application/json' -d '{"query": "mutation M { newTodo: createTodo(text: \"This is a todo mutation example\") { text done } }"}'
//
// Any of the above would return the following output:
// {
// "data": {
// "newTodo": {
// "done": false,
// "text": "This is a todo mutation example"
// }
// }
// }
}
@Luis-Enrique1
Copy link

gra.go:48:5: cannot use func literal (type func(graphql.ResolveParams) interface {}

@donvito
Copy link

donvito commented Oct 3, 2019

This works

Resolve: func(params graphql.ResolveParams) (interface{}, error) {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment