graphql

package module
v0.0.0-...-c035509 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 17, 2026 License: BSD-3-Clause Imports: 4 Imported by: 0

README

go-ruby-graphql/graphql

graphql — go-ruby-graphql

License Go CGO Coverage

A pure-Go (no cgo) reimplementation of the public surface of Ruby's graphql gem (graphql-ruby) — build a GraphQL schema from a set of root types and execute query documents against it, getting back a result whose data / errors shape matches graphql-ruby exactly.

It is a schema-and-execution façade for go-embedded-ruby, but a standalone, reusable module with no dependency on the Ruby runtime, and entirely self-contained: a schema and its queries run in-process, no network.

What it consumes

Execution is not reimplemented. This package is a thin, Ruby-flavoured façade over github.com/graphql-go/graphql, a mature pure-Go implementation of the GraphQL specification — lexer, parser, validator, type system, executor and introspection. Every type constructor wraps the corresponding graphql-go type, and Schema.Execute delegates to the graphql-go executor, then reshapes the result into graphql-ruby's Hash form.

Relationship to graphql-ruby

graphql-ruby's headline API is a large class-macro DSL — types are Ruby classes inheriting from GraphQL::Schema::Object and friends, with fields declared by the field macro. That class-based DSL is replaced here by an equivalent programmatic schema builder: the New…Type constructors stand in for the corresponding GraphQL:: classes, and a field's Resolve function stands in for a resolver method. What is preserved faithfully is the runtime contract — the type system, execution semantics, introspection, and the exact shape of the result and its errors entries (message, locations, path).

graphql-ruby this package
GraphQL::Schema + .execute(query, variables:, context:, operation_name:) NewSchema + Schema.Execute(query, ExecuteParams{…})
GraphQL::ObjectType / field / argument NewObjectType / Field / Argument
Int/Float/String/Boolean/ID Int Float String Boolean ID
custom scalar (coerce_input/coerce_result) NewScalarType (ParseValue/Serialize)
GraphQL::EnumType NewEnumType
GraphQL::InterfaceType + resolve_type NewInterfaceType + ResolveType
GraphQL::UnionType + resolve_type NewUnionType + ResolveType
GraphQL::InputObjectType NewInputObjectType
[T] / T! ListType(T) / NonNullType(T)
GraphQL::ExecutionError ExecutionError / NewExecutionError

Usage

queryType := graphql.NewObjectType(graphql.ObjectTypeConfig{
    Name: "Query",
    Fields: graphql.FieldMap{
        "hero": {
            Type: graphql.String,
            Resolve: func(p graphql.ResolveParams) (interface{}, error) {
                return "R2-D2", nil
            },
        },
    },
})

schema, _ := graphql.NewSchema(graphql.SchemaConfig{Query: queryType})

result := schema.Execute(`{ hero }`)
result.Data()   // map[string]interface{}{"hero": "R2-D2"}
result.Errors() // nil

Variables, fragments (named and inline), field aliases, the @include / @skip directives, and the __schema / __type introspection fields are all supported. A resolver returning an *ExecutionError (or any error) collects a field error at the current path and nulls the field, exactly as a raised GraphQL::ExecutionError does in graphql-ruby; a document that fails to parse or validate yields a result carrying only errors, with no data key.

Conformance

  • Pure Go, CGO=0 — no C dependencies.
  • 100% test coverage, -race clean.
  • 6 × 64-bit arches — amd64, arm64, riscv64, loong64, ppc64le, and s390x (big-endian), the last four under qemu-user in CI.
  • 3 OSes — Linux, macOS, Windows.
  • BSD-3-Clause licensed.

License

BSD-3-Clause — see LICENSE. Copyright the go-ruby-graphql/graphql authors.

WebAssembly

Being pure Go (CGO=0), this library also compiles to WebAssembly — both GOOS=js GOARCH=wasm (browser / Node.js) and GOOS=wasip1 GOARCH=wasm (WASI). CI builds both targets on every push, alongside the six 64-bit native/qemu arches.

GOOS=js     GOARCH=wasm go build ./...   # browser / Node
GOOS=wasip1 GOARCH=wasm go build ./...   # WASI (wasmtime, wasmer, wasmedge, …)

Documentation

Overview

Package graphql is a pure-Go (cgo-free) reimplementation of the public surface of Ruby's graphql gem (graphql-ruby): it builds a GraphQL schema from a set of root types and executes query documents against it, returning a result Hash whose data / errors shape matches graphql-ruby.

Relationship to graphql-ruby

graphql-ruby's headline API is a large class-macro DSL — types are Ruby classes that inherit from GraphQL::Schema::Object, GraphQL::Schema::Enum and friends, and fields are declared with the `field` macro. That class-based DSL is replaced here by an equivalent programmatic schema builder: the constructor functions NewObjectType, NewEnumType, NewInterfaceType, NewUnionType, NewInputObjectType and NewScalarType, composed with ListType and NonNullType, stand in for the corresponding GraphQL:: classes, and a Field's Resolve function stands in for a resolver method. What is preserved faithfully is the runtime contract: the type system, query execution semantics, introspection, and — crucially — the exact shape of the returned result and of the entries in its "errors" array (message, locations, path).

Consuming the Go ecosystem

Execution is not reimplemented. This package is a thin, Ruby-flavoured façade over github.com/graphql-go/graphql, a mature pure-Go implementation of the GraphQL specification (lexer, parser, validator, type system, executor and introspection). Every type constructor wraps the corresponding graphql-go type, and Schema.Execute delegates to graphql-go's executor, then reshapes the result into graphql-ruby's Hash form. Because the whole pipeline is pure Go with no network dependency, a schema and its queries run entirely in-process.

The type system

The five built-in scalars are the package values Int, Float, String, Boolean and ID; custom scalars are built with NewScalarType (Serialize mirrors coerce_result and ParseValue mirrors coerce_input). Object types are built with NewObjectType from a FieldMap; each Field has a Type, optional Args (each an Argument with an optional DefaultValue) and a Resolve function. Interfaces and unions (NewInterfaceType / NewUnionType) use a ResolveType hook to map a runtime value to its concrete object type, mirroring graphql-ruby's resolve_type. Input objects (NewInputObjectType) provide structured arguments.

Executing queries

schema, err := graphql.NewSchema(graphql.SchemaConfig{Query: queryType})
result := schema.Execute(`{ hero { name } }`, graphql.ExecuteParams{
	Variables:     map[string]interface{}{"id": "1000"},
	OperationName: "HeroQuery",
})
data := result.Data()     // map[string]interface{}, or nil
errs := result.Errors()   // []map[string]interface{}, or nil

Variables, fragments (named and inline), field aliases, the @include and @skip directives, and the __schema / __type introspection fields are all supported by the underlying executor. A resolver that returns an *ExecutionError (or any error) collects a field error at the current path and resolves the field to null, exactly as a raised GraphQL::ExecutionError does in graphql-ruby; a document that fails to parse or validate yields a result carrying only the "errors" array, with no "data" key.

Index

Constants

This section is empty.

Variables

View Source
var (
	Int     = &ScalarType{gql.Int}
	Float   = &ScalarType{gql.Float}
	String  = &ScalarType{gql.String}
	Boolean = &ScalarType{gql.Boolean}
	ID      = &ScalarType{gql.ID}
)

The five built-in scalars, mirroring GraphQL::Types::Int, ::Float, ::String, ::Boolean and ::ID.

Functions

This section is empty.

Types

type Argument

type Argument struct {
	Type         Type
	DefaultValue interface{}
	Description  string
}

Argument mirrors GraphQL::Argument: a named input to a field.

type ArgumentMap

type ArgumentMap map[string]*Argument

ArgumentMap maps argument names to their definitions.

type EnumType

type EnumType struct {
	// contains filtered or unexported fields
}

EnumType mirrors GraphQL::EnumType.

func NewEnumType

func NewEnumType(cfg EnumTypeConfig) *EnumType

NewEnumType creates an enum type (GraphQL::EnumType).

type EnumTypeConfig

type EnumTypeConfig struct {
	Name        string
	Description string
	Values      EnumValueMap
}

EnumTypeConfig configures an enum type.

type EnumValue

type EnumValue struct {
	// Value is the internal Go value this enum member coerces to; when nil the
	// member's name is used, mirroring graphql-ruby.
	Value             interface{}
	Description       string
	DeprecationReason string
}

EnumValue mirrors a single graphql-ruby enum value definition.

type EnumValueMap

type EnumValueMap map[string]*EnumValue

EnumValueMap maps enum member names to their definitions.

type ExecuteParams

type ExecuteParams struct {
	Variables     map[string]interface{}
	Context       context.Context
	OperationName string
	RootValue     map[string]interface{}
}

ExecuteParams carries the optional keyword arguments of GraphQL::Schema#execute: query variables, a per-request context, the operation to run when the document defines several, and a root value handed to the query root's resolvers.

type ExecutionError

type ExecutionError struct {
	Message string
	// Extensions is attached to the formatted error under "extensions", mirroring
	// graphql-ruby's error extensions.
	Extensions map[string]interface{}
}

ExecutionError mirrors GraphQL::ExecutionError. A resolver returns one (or any error) to signal a handled, client-facing failure: the field resolves to null and an entry is added to the response "errors" array with the field's path and source location, exactly as graphql-ruby does when a resolver raises a GraphQL::ExecutionError.

func NewExecutionError

func NewExecutionError(message string) *ExecutionError

NewExecutionError builds an ExecutionError with the given message.

func (*ExecutionError) Error

func (e *ExecutionError) Error() string

Error implements the error interface.

type Field

type Field struct {
	Type              Type
	Description       string
	Args              ArgumentMap
	Resolve           ResolveFn
	DeprecationReason string
}

Field mirrors GraphQL::Field: a named, typed, resolvable member of an object or interface type.

type FieldMap

type FieldMap map[string]*Field

FieldMap maps field names to their definitions.

type InputField

type InputField struct {
	Type         Type
	DefaultValue interface{}
	Description  string
}

InputField mirrors a single field of an input object.

type InputFieldMap

type InputFieldMap map[string]*InputField

InputFieldMap maps input-field names to their definitions.

type InputObjectType

type InputObjectType struct {
	// contains filtered or unexported fields
}

InputObjectType mirrors GraphQL::InputObjectType: a composite input type used for structured arguments.

func NewInputObjectType

func NewInputObjectType(cfg InputObjectTypeConfig) *InputObjectType

NewInputObjectType creates an input object type (GraphQL::InputObjectType).

type InputObjectTypeConfig

type InputObjectTypeConfig struct {
	Name        string
	Description string
	Fields      InputFieldMap
}

InputObjectTypeConfig configures an input object type.

type InterfaceType

type InterfaceType struct {
	// contains filtered or unexported fields
}

InterfaceType mirrors GraphQL::InterfaceType: an abstract type defining a set of fields that implementing object types must provide.

func NewInterfaceType

func NewInterfaceType(cfg InterfaceTypeConfig) *InterfaceType

NewInterfaceType creates an interface type (GraphQL::InterfaceType).

type InterfaceTypeConfig

type InterfaceTypeConfig struct {
	Name        string
	Description string
	Fields      FieldMap
	// ResolveType maps a runtime value to the concrete object type that
	// represents it, mirroring graphql-ruby's resolve_type hook.
	ResolveType func(value interface{}) *ObjectType
}

InterfaceTypeConfig configures an interface type.

type ObjectType

type ObjectType struct {
	// contains filtered or unexported fields
}

ObjectType mirrors GraphQL::ObjectType: a composite type with named, resolvable fields. Query, Mutation and Subscription roots are ordinary object types.

func NewObjectType

func NewObjectType(cfg ObjectTypeConfig) *ObjectType

NewObjectType creates an object type (GraphQL::ObjectType).

type ObjectTypeConfig

type ObjectTypeConfig struct {
	Name        string
	Description string
	Fields      FieldMap
	// Interfaces lists the interface types this object implements.
	Interfaces []*InterfaceType
}

ObjectTypeConfig configures an object type.

type ResolveFn

type ResolveFn func(p ResolveParams) (interface{}, error)

ResolveFn is the field-resolver seam: given the resolve parameters it returns the field's value or an error. Returning an *ExecutionError (or any error) collects a field error at the current path, matching graphql-ruby.

type ResolveParams

type ResolveParams struct {
	Source  interface{}
	Args    map[string]interface{}
	Context context.Context
	// contains filtered or unexported fields
}

ResolveParams is passed to a field's resolver. It mirrors the object handed to a graphql-ruby resolver method: the parent object (Source), the coerced arguments (Args) and the per-request context.

type Result

type Result map[string]interface{}

Result mirrors the Hash returned by GraphQL::Schema#execute. It always exposes a "data" key for a query that parsed and validated (its value may be nil), and an "errors" key holding the collected errors when any occurred. A query that fails to parse or validate carries only "errors", with no "data" key — the same shape graphql-ruby produces.

func (Result) Data

func (r Result) Data() map[string]interface{}

Data returns the "data" payload as a map, or nil when absent or null.

func (Result) Errors

func (r Result) Errors() []map[string]interface{}

Errors returns the collected errors in graphql-ruby's hash shape: each entry has a "message" and, where available, "locations" and "path". It returns nil when the result carries no errors.

func (Result) HasErrors

func (r Result) HasErrors() bool

HasErrors reports whether the result carries any errors.

type ScalarType

type ScalarType struct {
	// contains filtered or unexported fields
}

ScalarType mirrors a GraphQL scalar (GraphQL::ScalarType). The five built-in scalars are exposed as the package-level values Int, Float, String, Boolean and ID; custom scalars are created with NewScalarType.

func NewScalarType

func NewScalarType(cfg ScalarTypeConfig) *ScalarType

NewScalarType creates a custom scalar type.

type ScalarTypeConfig

type ScalarTypeConfig struct {
	Name        string
	Description string
	// Serialize coerces an internal value to the value sent to the client
	// (graphql-ruby's coerce_result). Required.
	Serialize func(value interface{}) interface{}
	// ParseValue coerces a client-supplied value (a variable) to the internal
	// representation (graphql-ruby's coerce_input). Optional; required if the
	// scalar is used as an input type.
	ParseValue func(value interface{}) interface{}
}

ScalarTypeConfig configures a custom scalar. It mirrors a graphql-ruby custom scalar's coerce_result (Serialize) and coerce_input (ParseValue) hooks. The literal form used inside a query document is coerced with the same ParseValue function after the raw literal node is reduced to a Go value.

type Schema

type Schema struct {
	// contains filtered or unexported fields
}

Schema mirrors GraphQL::Schema: a validated type system rooted at a query type (and optionally mutation and subscription types) against which query documents are executed.

func NewSchema

func NewSchema(cfg SchemaConfig) (*Schema, error)

NewSchema builds a schema from its root types. It returns an error when the type system is invalid (for example a missing query root or a malformed type), mirroring the failure raised by GraphQL::Schema at definition time.

func (*Schema) Execute

func (s *Schema) Execute(query string, params ...ExecuteParams) Result

Execute runs a query document against the schema and returns a graphql-ruby -shaped Result (data / errors). The optional ExecuteParams mirrors the keyword arguments of GraphQL::Schema#execute(query, variables:, context:, operation_name:); at most one may be supplied.

type SchemaConfig

type SchemaConfig struct {
	Query        *ObjectType
	Mutation     *ObjectType
	Subscription *ObjectType
	Types        []Type
}

SchemaConfig configures a schema. Query is required; Mutation and Subscription are optional root types. Types lists extra types that are not reachable from the roots by field traversal (for example the concrete members of a union that is only returned via an interface), mirroring graphql-ruby's orphan_types / extra type registration.

type Type

type Type interface {
	// contains filtered or unexported methods
}

Type is a member of the GraphQL type system. It mirrors the abstract GraphQL::Schema::Member hierarchy of graphql-ruby: every concrete type (scalars, objects, enums, interfaces, unions, input objects, and the List / NonNull wrappers) satisfies it, so it may be used as a field's return type or an argument's input type.

The underlying graphql-go type is intentionally hidden behind an unexported accessor so that callers program against this package's Ruby-flavoured surface rather than graphql-go directly.

func ListType

func ListType(of Type) Type

ListType wraps a type as a GraphQL list (GraphQL::ListType, the Ruby [T]).

func NonNullType

func NonNullType(of Type) Type

NonNullType wraps a type as non-null (GraphQL::NonNullType, the Ruby T!).

type UnionType

type UnionType struct {
	// contains filtered or unexported fields
}

UnionType mirrors GraphQL::UnionType: a type that is exactly one of a fixed set of object types.

func NewUnionType

func NewUnionType(cfg UnionTypeConfig) *UnionType

NewUnionType creates a union type (GraphQL::UnionType).

type UnionTypeConfig

type UnionTypeConfig struct {
	Name        string
	Description string
	Types       []*ObjectType
	// ResolveType maps a runtime value to its concrete member type.
	ResolveType func(value interface{}) *ObjectType
}

UnionTypeConfig configures a union type.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL