This page is a graphql golang tutorial in the narrow sense: it shows golang graphql and go graphql examples using graphql-go/graphql, which builds schemas in Go and executes operations with graphql.Do. If you searched graphql golang example, golang graphql example, or graphql golang tutorial, you will get a minimal schema, a resolver that reads context, and an HTTP server with Playground. Searches for graphql mongodb golang or golang graphql mongodb are covered in a short dedicated subsection—GraphQL stays agnostic to storage, and MongoDB lives behind your resolvers.
Tested with Go 1.24 on Linux.
GraphQL and Go at a glance
GraphQL is a query language and runtime: the client sends a document describing the shape of data it wants, and the server walks a typed graph you define. graphql go stacks usually pair a schema library (here graphql-go) with net/http or a router. graphql go differs from typical REST in that one POST handler can serve many “logical endpoints” encoded as queries.
Golang graphql example: define a schema and run graphql.Do
Install the library in your module:
go get github.com/graphql-go/graphql@latestThe program below defines a single hello field on the root query type and prints the JSON-like result of graphql.Do.
package main
import (
"encoding/json"
"fmt"
"log"
"github.com/graphql-go/graphql"
)
func main() {
fields := graphql.Fields{
"hello": &graphql.Field{
Type: graphql.String,
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
return "Welcome to GoLinuxcloud!", nil
},
},
}
rootQuery := graphql.ObjectConfig{Name: "RootQuery", Fields: fields}
schema, err := graphql.NewSchema(graphql.SchemaConfig{
Query: graphql.NewObject(rootQuery),
})
if err != nil {
log.Fatalf("schema: %v", err)
}
query := `{ hello }`
r := graphql.Do(graphql.Params{Schema: schema, RequestString: query})
if len(r.Errors) > 0 {
log.Fatalf("errors: %+v", r.Errors)
}
out, _ := json.Marshal(r)
fmt.Println(string(out))
}Running go run . prints one line of JSON containing data.hello with the welcome string.
Resolvers, arguments, and context
Resolvers receive graphql.ResolveParams: p.Args holds GraphQL arguments, and p.Context carries request-scoped values from the standard context package (auth, tracing, database handles).
package main
import (
"context"
"encoding/json"
"fmt"
"log"
"github.com/graphql-go/graphql"
)
func main() {
schema, err := graphql.NewSchema(graphql.SchemaConfig{
Query: graphql.NewObject(graphql.ObjectConfig{
Name: "Query",
Fields: graphql.Fields{
"value": &graphql.Field{
Type: graphql.String,
Args: graphql.FieldConfigArgument{
"key": &graphql.ArgumentConfig{Type: graphql.String},
},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
return p.Context.Value(p.Args["key"]), nil
},
},
},
}),
})
if err != nil {
log.Fatal(err)
}
query := `{ value(key:"User1") }`
result := graphql.Do(graphql.Params{
Schema: schema,
RequestString: query,
Context: context.WithValue(context.TODO(), "User1", "xyz"),
})
out, _ := json.Marshal(result)
fmt.Println(string(out))
}Running it prints JSON where data.value is xyz, showing the key from the query mapped through p.Args into context.Value.
GraphQL HTTP server with Playground (graphql golang tutorial)
For browsers and API gateways you expose GraphQL over HTTP. The graphql-go/handler package wraps a graphql.Schema as an http.Handler and can enable GraphQL Playground for local experiments.
go get github.com/graphql-go/handler@latestThe following self-contained server keeps sample students in a string constant (no data.json on disk). Save as main.go, run go run ., and open http://localhost:8080/graphql for Playground while it is running.
package main
import (
"encoding/json"
"errors"
"log"
"net/http"
"github.com/graphql-go/graphql"
"github.com/graphql-go/handler"
)
const dataJSON = `[
{"id":1,"name":"Dan","passed":true},
{"id":2,"name":"Bob","passed":true}
]`
var students []*Student
type Student struct {
ID int `json:"id"`
Name string `json:"name"`
Passed bool `json:"passed"`
}
func listStudents() ([]*Student, error) { return students, nil }
func getStudent(id int) (*Student, error) {
for _, s := range students {
if s.ID == id {
return s, nil
}
}
return nil, errors.New("student not found")
}
func main() {
if err := json.Unmarshal([]byte(dataJSON), &students); err != nil {
log.Fatal(err)
}
studentType := graphql.NewObject(graphql.ObjectConfig{
Name: "Student",
Fields: graphql.Fields{
"id": &graphql.Field{
Type: graphql.Int,
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
if s, ok := p.Source.(*Student); ok {
return s.ID, nil
}
return nil, nil
},
},
"name": &graphql.Field{
Type: graphql.String,
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
if s, ok := p.Source.(*Student); ok {
return s.Name, nil
}
return nil, nil
},
},
"passed": &graphql.Field{
Type: graphql.Boolean,
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
if s, ok := p.Source.(*Student); ok {
return s.Passed, nil
}
return nil, nil
},
},
},
})
queryType := graphql.NewObject(graphql.ObjectConfig{
Name: "Query",
Fields: graphql.Fields{
"students": &graphql.Field{
Type: graphql.NewList(studentType),
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
return listStudents()
},
},
"student": &graphql.Field{
Type: studentType,
Args: graphql.FieldConfigArgument{
"id": &graphql.ArgumentConfig{Type: graphql.NewNonNull(graphql.Int)},
},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
return getStudent(p.Args["id"].(int))
},
},
},
})
schema, err := graphql.NewSchema(graphql.SchemaConfig{Query: queryType})
if err != nil {
log.Fatal(err)
}
h := handler.New(&handler.Config{
Schema: &schema,
Pretty: true,
GraphiQL: false,
Playground: true,
})
http.Handle("/graphql", h)
log.Fatal(http.ListenAndServe(":8080", nil))
}Example query in Playground:
{
students { id name passed }
}Example query with an argument:
{
student(id: 1) { name }
}Turn off Playground and GraphiQL before exposing the handler on the public internet.
Graphql mongodb golang and golang graphql mongodb
GraphQL does not speak MongoDB directly: your resolvers are plain Go functions. A typical golang graphql mongodb layout is: connect with mongo.Connect in main, obtain a *mongo.Collection, then either close over that collection in resolver functions or store it in context.Context (for example with a private context key type) so each Resolve can run FindOne, InsertOne, or aggregation pipelines. That keeps protocol concerns in GraphQL and persistence in the driver. For CRUD basics without GraphQL, read Golang MongoDB first, then lift the same calls into resolvers.
gqlgen and other stacks
This graphql golang tutorial uses code-first schema construction. For SDL-first code generation and stricter typing, many teams choose gqlgen. Both are valid answers to graphql go depending on project size and whether you want .graphql files as the source of truth.
Summary
A practical graphql golang tutorial for small services starts with graphql.NewSchema, graphql.Do for scripts, and graphql-go/handler for HTTP. golang graphql example code boils down to types built with graphql.NewObject, field resolvers that return Go values, and optional arguments plus context for per-request data. graphql mongodb golang work is ordinary Mongo driver usage inside those resolvers, not a separate GraphQL feature. Compare approaches (graphql-go versus gqlgen), disable Playground in production, and keep learning HTTP details in the Go HTTP guide.
References
Frequently Asked Questions
1. What is the simplest golang graphql example?
graphql.Field, build a graphql.Schema with graphql.NewSchema, then run graphql.Do with your query string; the result is JSON-compatible data plus errors.2. How does this graphql golang tutorial relate to REST?
net/http, but the handler parses GraphQL bodies instead of mapping one path per resource.3. How do I wire graphql mongodb golang or golang graphql mongodb?
*mongo.Collection in main, pass it into resolvers (closure or context.Value), and run queries inside Resolve using the official Go driver—see the MongoDB guide linked in the body.4. Should I use graphql-go or gqlgen for go graphql?
graphql-go/graphql is small and code-first; gqlgen generates Go from schema and scales better for large teams—pick based on whether you want hand-written schema in Go or SDL-first workflows.
