Complete GraphQL implementation in Go with schema definition, query execution, and validation.
A complete GraphQL implementation in Go following the official reference implementation. Supports queries, mutations, subscriptions, schema definition, validation, and execution.
go get github.com/graphql-go/graphqlimport "github.com/graphql-go/graphql"
// 1. Define schema
schema, _ := graphql.NewSchema(graphql.SchemaConfig{
Query: graphql.NewObject(graphql.ObjectConfig{
Name: "RootQuery",
Fields: graphql.Fields{
"hello": &graphql.Field{
Type: graphql.String,
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
return "world", nil
},
},
},
}),
})
// 2. Execute query
result := graphql.Do(graphql.Params{
Schema: schema,
RequestString: `{ hello }`,
})| Capability | Description | Reference |
|---|---|---|
| Schema Definition | Define types, interfaces, unions, enums, and scalars | Schema → |
| Query Execution | Execute queries and mutations with variables | Execution → |
| Subscriptions | Real-time updates via subscription operations | Execution → |
| Validation | Validate documents against schema rules | Validation → |
| AST & Parsing | Parse GraphQL to AST, traverse and transform | Language → |
| Error Handling | Structured errors with location info | Errors → |
func NewSchema(config SchemaConfig) (Schema, error)
func NewObject(config ObjectConfig) *Object
func NewInterface(config InterfaceConfig) *Interface
func NewUnion(config UnionConfig) *Union
func NewEnum(config EnumConfig) *Enum
func NewScalar(config ScalarConfig) *Scalar
func NewInputObject(config InputObjectConfig) *InputObjectfunc Do(p Params) *Result
func Execute(p ExecuteParams) *Result
func Subscribe(p Params) chan *Result
func ExecuteSubscription(p ExecuteParams) chan *Resultfunc ValidateDocument(schema *Schema, astDoc *ast.Document, rules []ValidationRuleFn) ValidationResultfunc Parse(p ParseParams) (*ast.Document, error)
func ParseValue(p ParseParams) (ast.Value, error)var Int *Scalar // 32-bit signed integer
var Float *Scalar // Double-precision float
var String *Scalar // UTF-8 text
var Boolean *Scalar // true/false
var ID *Scalar // Unique identifier (serialized as string)
var DateTime *Scalar // RFC 3339 date-time stringfunc NewList(ofType Type) *List // [Type]
func NewNonNull(ofType Type) *NonNull // Type!Common patterns:
graphql.NewList(userType) // [User]
graphql.NewNonNull(graphql.String) // String!
graphql.NewNonNull(graphql.NewList(userType)) // [User]!
graphql.NewList(graphql.NewNonNull(userType)) // [User!]// Pass context to resolvers
result := graphql.Do(graphql.Params{
Schema: schema,
Context: context.WithValue(ctx, "userID", "123"),
})
// Access in resolver
resolve: func(p graphql.ResolveParams) (interface{}, error) {
userID := p.Context.Value("userID").(string)
return fetchUser(userID)
}Resolvers return (interface{}, error):
resolve: func(p graphql.ResolveParams) (interface{}, error) {
val, err := fetchData(p.Args["id"])
if err != nil {
return nil, err // Becomes FormattedError in Result.Errors
}
return val, nil
}Use thunks (functions) for fields/interfaces that reference types not yet defined:
var personType = graphql.NewObject(graphql.ObjectConfig{
Name: "Person",
Fields: graphql.FieldsThunk(func() graphql.Fields {
return graphql.Fields{
"friends": &graphql.Field{Type: graphql.NewList(personType)},
}
}),
})Arguments come as map[string]interface{} - always type assert:
id := p.Args["id"].(string)
limit := p.Args["limit"].(int)The default resolver returns nil for missing fields. Handle appropriately in parent resolvers.
For detailed documentation, see the reference section.
Install with Tessl CLI
npx tessl i tessl/golang-github-com--graphql-go--graphql