gql

package module
v0.5.1 Latest Latest
Warning

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

Go to latest
Published: Jul 5, 2021 License: MIT Imports: 12 Imported by: 0

README

gql

tests PkgGoDev Coverage Status

Note: As the project is still in WIP, there can be breaking changes which may break previous versions.

This project aims to fulfill some of the most common feature requests missing from existing packages, or ones that could be done differently.

Roadmap for the package

  • Custom scalars
  • Extensions
  • Subscriptions
  • Apollo Federation
  • Custom directives
    • Field directives
    • Executable directives
    • Type System directives
  • Opentracing
  • Query complexity
  • Apollo File Upload
  • Custom validation for input and arguments
  • Access to the requested fields in a resolver
  • Custom rules-based introspection
  • Converting structs into GraphQL types
  • Parse inputs into structs

Examples

There are examples in the examples folder, these are only uses this gql package, they don't have any other dependencies.

Additional examples can be found for Apollo Federation, Subscriptions in the rigglo/gql-examples repository.

Getting started

Defining a type, an object is very easy, let's visit a pizzeria as an example.

var PizzaType = &gql.Object{  
   Name: "Pizza",  
   Fields: gql.Fields{
      "id": &gql.Field{
         Description: "id of the pizza",
         Type:        gql.ID,
      },
      "name": &gql.Field{
         Description: "name of the pizza",
         Type:        gql.String,
      },
      "size": &gql.Field{
         Description: "size of the pizza (in cm)",
         Type:        gql.Int,
      },
   },
}

Next, we need a way to get our pizza, to list them, so let's define the query.

var RootQuery = &gql.Object{  
   Name: "RootQuery",  
   Fields: gql.Fields{
      "pizzas": &gql.Field{
         Description: "lists all the pizzas",    
         Type:        gql.NewList(PizzaType),
         Resolver: func(ctx gql.Context) (interface{}, error) {
            return []Pizza{
               Pizza{
                  ID:1, 
                  Name: "Veggie", 
                  Size: 32,
               },
               Pizza{
                  ID:2, 
                  Name: "Salumi", 
                  Size: 45,
               },
            }, nil
         },
      },
   }, 
}

To have a schema defined, you need the following little code, that connects your root query and mutations (if there are) to your schema, which can be later executed.

var PizzeriaSchema = &gql.Schema{
   Query: RootQuery,
}

At this point, what's only left is an executor, so we can run our queries, and a handler to be able to serve our schema.

For our example, let's use the default executor, but if you want to experiment, customise it, add extensions, you can create your own the gql.NewExecutor function.  Let's fire up our handler using the github.com/rigglo/gql/pkg/handler package and also enable the playground, so we can check it from our browser.

func main() {
   http.Handle("/graphql", handler.New(handler.Config{
      Executor:   gql.DefaultExecutor(PizzeriaSchema),
      Playground: true,
   }))
   if err := http.ListenAndServe(":9999", nil); err != nil {
      panic(err)
   }
}

After running the code, you can go to the http://localhost:9999/graphql address in your browser and see the GraphQL Playground, and you can start playing with it.

NOTES
Directives

Adding directives in the type system is possible, but currently only the field directives are being executed.

Apollo Federation

The support for Apollo Federation is provided by the github.com/rigglo/gql/pkg/federation package, which adds the required fields, types and directives to your schema.

SDL

The support for generating SDL from the Schema is not production ready, in most cases it's enough, but it requires some work, use it for your own risk.

Documentation

Overview

Package gql is a GraphQL implementation

NOTE: THIS PACKAGE IS STILL UNDER DEVELOPMENT

About gql

The gql package aims to fulfill a few extra features that I missed in other packages, be as efficient as possible and 100% close to the GraphQL specificaton. The idea behind the package is to achive a really easy learning curve, but still leave many option to customize everything to your benefit.

Just a few features that are already built in

  • Custom scalars
  • request validation (still in progress)
  • handler

Getting started

We'll build our own pizzeria, for that we need a `Pizza` type to store the properties of the pizzas. At the beginning, we only store the name, size and if the pizza is spicy.

var PizzaType = &gql.Object{
	Name: "Pizza",
	Fields: gql.Fields{
		"name": &gql.Field{
			Description: "name of the pizza",
			Type: gql.String,
		},
		"size": &gql.Field{
			Description: "size of the pizza (in cm)",
			Type: gql.Int,
		},
		"is_spicy": &gql.Field{
			Description: "is the pizza spicy or not",
			Type: gql.Boolean,
		},
	},
}

Since we have a type, we need to build a query to be able to access to it. The root query will be the starting point of any query, fields in this type represents be all the available query fields. Let's add the root query with a "pizzas" query, which will return a list of the available pizzas. Since we need a little logic here to return the available pizzas, we'll use a resolver.

var RootQuery = &gql.Object{
	Name: "Query",
	Fields: gql.Fields{
		"pizzas": &gql.Field{
			Type: gql.NewList(PizzaType),
			Resolver: func(c gql.Context) (interface{}, error) {
				return []Pizza{
					Pizza{
						Name: "songoku",
						Size: 32,
						IsSpicy: false,
					},
					Pizza{
						Name: "hell-o",
						Size: 40,
						IsSpicy: true,
					},
				}, nil
			},
		},
	},
}

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Argument

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

Argument defines an argument for a field or a directive. Default value can be provided in case it's not populated during a query. The type of the argument must be an input type.

func (*Argument) IsDefaultValueSet added in v0.2.0

func (a *Argument) IsDefaultValueSet() bool

IsDefaultValueSet helps to know if the default value was set or not

type ArgumentDirective added in v0.2.0

type ArgumentDirective interface {
	VisitArgument(context.Context, Argument)
}

type Arguments

type Arguments map[string]*Argument

Arguments for fields and directives

func (Arguments) String added in v0.5.0

func (args Arguments) String() (out string)

type CoerceInputFunc added in v0.2.0

type CoerceInputFunc func(interface{}) (interface{}, error)

CoerceInputFunc coerces the input value to a type which will be used during field resolve

type CoerceResultFunc added in v0.2.0

type CoerceResultFunc func(interface{}) (interface{}, error)

CoerceResultFunc coerces the result of a field resolve to the final format

type Context added in v0.2.0

type Context interface {
	// Context returns the original context that was given to the executor
	Context() context.Context
	// Path of the field
	Path() []interface{}
	// Args of the field
	Args() map[string]interface{}
	// Parent object's data
	Parent() interface{}
}

Context for the field resolver functions

type CustomError added in v0.2.0

type CustomError interface {
	error
	GetMessage() string
	GetExtensions() map[string]interface{}
}

func NewError added in v0.2.0

func NewError(msg string, extensions map[string]interface{}) CustomError

NewError ...

type Directive added in v0.0.2

type Directive interface {
	GetName() string
	GetDescription() string
	GetArguments() Arguments
	GetLocations() []DirectiveLocation
}

type DirectiveLocation added in v0.2.0

type DirectiveLocation string
const (
	// Executable directive locations
	QueryLoc              DirectiveLocation = "QUERY"
	MutationLoc           DirectiveLocation = "MUTATION"
	SubscriptionLoc       DirectiveLocation = "SUBSCRIPTION"
	FieldLoc              DirectiveLocation = "FIELD"
	FragmentDefinitionLoc DirectiveLocation = "FRAGMENT_DEFINITION"
	FragmentSpreadLoc     DirectiveLocation = "FRAGMENT_SPREAD"
	InlineFragmentLoc     DirectiveLocation = "INLINE_FRAGMENT"

	// Type System directive locations
	SchemaLoc               DirectiveLocation = "SCHEMA"
	ScalarLoc               DirectiveLocation = "SCALAR"
	ObjectLoc               DirectiveLocation = "OBJECT"
	FieldDefinitionLoc      DirectiveLocation = "FIELD_DEFINITION"
	ArgumentDefinitionLoc   DirectiveLocation = "ARGUMENT_DEFINITION"
	InterfaceLoc            DirectiveLocation = "INTERFACE"
	UnionLoc                DirectiveLocation = "UNION"
	EnumLoc                 DirectiveLocation = "ENUM"
	EnumValueLoc            DirectiveLocation = "ENUM_VALUE"
	InputObjectLoc          DirectiveLocation = "INPUT_OBJECT"
	InputFieldDefinitionLoc DirectiveLocation = "INPUT_FIELD_DEFINITION"
)

type Directives added in v0.2.0

type Directives []Directive

type Enum added in v0.0.3

type Enum struct {
	Name        string
	Description string
	Directives  TypeSystemDirectives
	Values      EnumValues
}

Enum types, like scalar types, also represent leaf values in a GraphQL type system. However Enum types describe the set of possible values.

func (*Enum) GetDescription added in v0.2.0

func (e *Enum) GetDescription() string

GetDescription returns the description of the Enum

func (*Enum) GetDirectives added in v0.2.0

func (e *Enum) GetDirectives() []TypeSystemDirective

GetDirectives returns all the directives set for the Enum

func (*Enum) GetKind added in v0.2.0

func (e *Enum) GetKind() TypeKind

GetKind returns the type kind, "Enum"

func (*Enum) GetName added in v0.2.0

func (e *Enum) GetName() string

GetName returns the name of the Enum

func (*Enum) GetValues added in v0.2.0

func (e *Enum) GetValues() []*EnumValue

GetValues returns the values for the Enum

func (*Enum) String added in v0.5.0

func (e *Enum) String() string

String implements the fmt.Stringer

type EnumDirective added in v0.2.0

type EnumDirective interface {
	VisitEnum(context.Context, Enum) *Enum
}

type EnumValue added in v0.0.3

type EnumValue struct {
	Name        string
	Description string
	Directives  TypeSystemDirectives
	Value       interface{}
}

EnumValue is one single value in an Enum

func (EnumValue) GetDescription added in v0.2.0

func (e EnumValue) GetDescription() string

GetDescription returns the description of the value

func (EnumValue) GetDirectives added in v0.2.0

func (e EnumValue) GetDirectives() []TypeSystemDirective

GetDirectives returns the directives set for the enum value

func (EnumValue) GetValue added in v0.2.0

func (e EnumValue) GetValue() interface{}

GetValue returns the actual value of the enum value This value is used in the resolver functions, the enum coerces this value.

func (EnumValue) IsDeprecated added in v0.2.0

func (e EnumValue) IsDeprecated() bool

IsDeprecated show if the deprecated directive is set for the enum value or not

type EnumValueDirective added in v0.2.0

type EnumValueDirective interface {
	VisitEnumValue(context.Context, EnumValue) *EnumValue
}

type EnumValues added in v0.0.3

type EnumValues []*EnumValue

EnumValues is an alias for a bunch of "EnumValue"s

type Error added in v0.2.0

type Error struct {
	Message    string                 `json:"message"`
	Locations  []*ErrorLocation       `json:"locations"`
	Path       []interface{}          `json:"path"`
	Extensions map[string]interface{} `json:"extensions,omitempty"`
}

Error for the Result of the validation/execution

func (*Error) Error added in v0.2.0

func (e *Error) Error() string

Error implements the error interface

type ErrorLocation added in v0.2.0

type ErrorLocation struct {
	Line   int `json:"line"`
	Column int `json:"column"`
}

ErrorLocation represents the location of an error in the query

type Errors added in v0.2.0

type Errors []*Error

Errors is an alias for a bunch of Error

type Executor added in v0.2.0

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

func DefaultExecutor added in v0.2.0

func DefaultExecutor(s *Schema) *Executor

func NewExecutor added in v0.2.0

func NewExecutor(c ExecutorConfig) *Executor

func (*Executor) Execute added in v0.2.0

func (e *Executor) Execute(ctx context.Context, p Params) *Result

func (*Executor) Subscribe added in v0.4.0

func (e *Executor) Subscribe(ctx context.Context, query string, operationName string, variables map[string]interface{}) (<-chan interface{}, error)

type ExecutorConfig added in v0.2.0

type ExecutorConfig struct {
	GoroutineLimit   int
	EnableGoroutines bool
	Schema           *Schema
	Extensions       []Extension
}

type Extension added in v0.2.1

type Extension interface {
	Init(ctx context.Context, p Params) context.Context
	GetName() string
	Call(ctx context.Context, e ExtensionEvent, args interface{})
	Result(ctx context.Context) interface{}
}

type ExtensionEvent added in v0.2.1

type ExtensionEvent uint
const (
	EventParseStart ExtensionEvent = iota
	EventParseFinish
	EventValidationStart
	EventValidationFinish
	EventExecutionStart
	EventExecutionFinish
	EventFieldResolverStart
	EventFieldResolverFinish
)

type Field

type Field struct {
	Description string
	Arguments   Arguments
	Type        Type
	Directives  TypeSystemDirectives
	Resolver    Resolver
}

Field for an object or interface

For Object, you can provide a resolver if you want to return custom data or have a something to do with the data. For Interfaces, there's NO need for resolvers, since they will NOT be executed.

func (*Field) GetArguments added in v0.2.0

func (f *Field) GetArguments() Arguments

GetArguments of the field

func (*Field) GetDescription added in v0.2.0

func (f *Field) GetDescription() string

GetDescription of the field

func (*Field) GetDirectives added in v0.2.0

func (f *Field) GetDirectives() []TypeSystemDirective

GetDirectives returns the directives set for the field

func (*Field) GetType added in v0.2.0

func (f *Field) GetType() Type

GetType returns the type of the field

func (*Field) IsDeprecated added in v0.2.0

func (f *Field) IsDeprecated() bool

IsDeprecated returns if the field is depricated

type FieldDefinitionDirective added in v0.2.0

type FieldDefinitionDirective interface {
	VisitFieldDefinition(context.Context, Field, Resolver) Resolver
}

type Fields

type Fields map[string]*Field

Fields is an alias for more Fields

func (Fields) Add added in v0.0.4

func (fs Fields) Add(name string, f *Field)

Add a field to the Fields

type InputField added in v0.0.5

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

InputField is a field for an InputObject. As an Argument, it can be used as an input too, can have a default value and must have an input type.

func (*InputField) IsDefaultValueSet added in v0.2.0

func (o *InputField) IsDefaultValueSet() bool

IsDefaultValueSet helps to know if the default value was set or not

type InputFieldDirective added in v0.2.0

type InputFieldDirective interface {
	VisitInputField(context.Context, InputField) *InputField
}

type InputFields added in v0.0.3

type InputFields map[string]*InputField

InputFields is just an alias for a bunch of "InputField"s

type InputObject added in v0.0.3

type InputObject struct {
	Description string
	Name        string
	Directives  TypeSystemDirectives
	Fields      InputFields
}

InputObject is an input object from the GraphQL type system. It must have a name and at least one input field set. Its fields can have default values if needed.

func (*InputObject) GetDescription added in v0.2.0

func (o *InputObject) GetDescription() string

GetDescription returns the description of the input object and also there to implement the Type interface

func (*InputObject) GetDirectives added in v0.2.0

func (o *InputObject) GetDirectives() []TypeSystemDirective

GetDirectives returns the directives set for the input object

func (*InputObject) GetFields added in v0.2.0

func (o *InputObject) GetFields() map[string]*InputField

GetFields returns the fields of the input object

func (*InputObject) GetKind added in v0.2.0

func (o *InputObject) GetKind() TypeKind

GetKind returns the kind of the type, "InputObject", and also there to implement the Type interface

func (*InputObject) GetName added in v0.2.0

func (o *InputObject) GetName() string

GetName returns the name of the input object and also there to implement the Type interface

func (*InputObject) String added in v0.5.0

func (o *InputObject) String() string

String implements the fmt.Stringer

type InputObjectDirective added in v0.2.0

type InputObjectDirective interface {
	VisitInputObject(context.Context, InputObject) *InputObject
}

type Interface added in v0.0.3

type Interface struct {
	Description  string
	Name         string
	Directives   TypeSystemDirectives
	Fields       Fields
	TypeResolver TypeResolver
}

Interface represent a list of named fields and their arguments. GraphQL objects can then implement these interfaces which requires that the object type will define all fields defined by those interfaces.

Fields on a GraphQL interface have the same rules as fields on a GraphQL object; their type can be Scalar, Object, Enum, Interface, or Union, or any wrapping type whose base type is one of those five.

func (*Interface) GetDescription added in v0.2.0

func (i *Interface) GetDescription() string

GetDescription returns the description of the interface

func (*Interface) GetDirectives added in v0.2.0

func (i *Interface) GetDirectives() []TypeSystemDirective

GetDirectives returns all the directives that are set to the interface

func (*Interface) GetFields added in v0.0.3

func (i *Interface) GetFields() map[string]*Field

GetFields returns all the fields that can be implemented on the interface

func (*Interface) GetKind added in v0.2.0

func (i *Interface) GetKind() TypeKind

GetKind returns the type kind, "Interface"

func (*Interface) GetName added in v0.2.0

func (i *Interface) GetName() string

GetName returns the name of the interface

func (*Interface) Resolve added in v0.2.0

func (i *Interface) Resolve(ctx context.Context, v interface{}) *Object

Resolve the return type of the interface

func (*Interface) String added in v0.5.0

func (i *Interface) String() string

String implements the fmt.Stringer

type InterfaceDirective added in v0.2.0

type InterfaceDirective interface {
	VisitInterface(context.Context, Interface) *Interface
}

type Interfaces added in v0.2.0

type Interfaces []*Interface

Interfaces is an alias for more and more graphql interface

type List added in v0.0.2

type List struct {
	Name        string
	Description string
	Wrapped     Type
}

List in the GraphQL Type System For creating a new List type, always use the `NewList` function

NewList(SomeType)

func (*List) GetDescription added in v0.2.0

func (l *List) GetDescription() string

GetDescription shows the description of the type

func (*List) GetKind added in v0.2.0

func (l *List) GetKind() TypeKind

GetKind returns the kind of the type, ListKind

func (*List) GetName added in v0.2.0

func (l *List) GetName() string

GetName returns the name of the type, "List"

func (*List) String added in v0.5.0

func (l *List) String() string

String implements the fmt.Stringer

func (*List) Unwrap added in v0.0.2

func (l *List) Unwrap() Type

Unwrap the inner type from the List

type Members added in v0.2.0

type Members []Type

Members is an alias for a list of types that are set for a Union

type NonNull added in v0.0.2

type NonNull struct {
	Name        string
	Description string
	Wrapped     Type
}

NonNull type from the GraphQL type system

func (*NonNull) GetDescription added in v0.2.0

func (l *NonNull) GetDescription() string

GetDescription returns the description of the NonNull type

func (*NonNull) GetKind added in v0.2.0

func (l *NonNull) GetKind() TypeKind

GetKind returns the kind of the type, NonNullKind

func (*NonNull) GetName added in v0.2.0

func (l *NonNull) GetName() string

GetName returns the name of the type, "NonNull"

func (*NonNull) String added in v0.5.0

func (l *NonNull) String() string

String implements the fmt.Stringer

func (*NonNull) Unwrap added in v0.0.2

func (l *NonNull) Unwrap() Type

Unwrap the inner type of the NonNull type

type Object

type Object struct {
	Description string
	Name        string
	Implements  Interfaces
	Directives  TypeSystemDirectives
	Fields      Fields
}

Object GraphQL queries are hierarchical and composed, describing a tree of information. While Scalar types describe the leaf values of these hierarchical queries, Objects describe the intermediate levels

They represent a list of named fields, each of which yield a value of a specific type.

Example code:

var RootQuery = &gql.Object{
	Name: "Query",
	Fields: gql.Fields{
		"hello": {
			Name: "hello",
			Type: gql.String,
			Resolver: func(ctx gql.Context) (interface{}, error) {
				return "world", nil
			},
		},
	},
}

All fields defined within an Object type must not have a name which begins with "__" (two underscores), as this is used exclusively by GraphQL’s introspection system.

func (*Object) AddField added in v0.2.0

func (o *Object) AddField(name string, f *Field)

AddFields lets you add fields to the object

func (*Object) DoesImplement added in v0.2.0

func (o *Object) DoesImplement(i *Interface) bool

DoesImplement helps decide if the object implements an interface or not

func (*Object) GetDescription added in v0.2.0

func (o *Object) GetDescription() string

GetDescription returns the description of the object

func (*Object) GetDirectives added in v0.2.0

func (o *Object) GetDirectives() []TypeSystemDirective

GetDirectives returns all the directives that are used on the object

func (*Object) GetFields added in v0.0.3

func (o *Object) GetFields() map[string]*Field

GetFields returns all the fields on the object

func (*Object) GetInterfaces added in v0.2.0

func (o *Object) GetInterfaces() []*Interface

GetInterfaces returns all the interfaces that the object implements

func (*Object) GetKind added in v0.2.0

func (o *Object) GetKind() TypeKind

GetKind returns the type kind, "Object"

func (*Object) GetName added in v0.2.0

func (o *Object) GetName() string

GetName returns the name of the object

func (*Object) String added in v0.5.0

func (o *Object) String() string

String implements the fmt.Stringer

type ObjectDirective added in v0.2.0

type ObjectDirective interface {
	VisitObject(context.Context, Object) *Object
}

type Params added in v0.0.3

type Params struct {
	Query         string                 `json:"query"`
	Variables     map[string]interface{} `json:"variables"`
	OperationName string                 `json:"operationName"`
}

type Resolver added in v0.2.0

type Resolver func(Context) (interface{}, error)

Resolver function that can resolve a field using the Context from the executor

type Result

type Result struct {
	Data       map[string]interface{} `json:"data,omitempty"`
	Errors     []*Error               `json:"errors,omitempty"`
	Extensions map[string]interface{} `json:"extensions,omitempty"`
}

func Execute added in v0.2.0

func Execute(ctx context.Context, s *Schema, p Params) *Result

type Scalar

type Scalar struct {
	Name             string
	Description      string
	Directives       TypeSystemDirectives
	CoerceResultFunc CoerceResultFunc
	CoerceInputFunc  CoerceInputFunc
	AstValidator     ScalarAstValueValidator
}

Scalar types represent primitive leaf values in a GraphQL type system. GraphQL responses take the form of a hierarchical tree; the leaves of this tree are typically GraphQL Scalar types (but may also be Enum types or null values)

var Boolean *Scalar = &Scalar{
	Name:        "Boolean",
	Description: "This is the built-in 'Boolean' scalar type",
	CoerceResultFunc: func(i interface{}) (interface{}, error) {
		if m, ok := i.(json.Marshaler); ok {
			return m, nil
		}
		return coerceBool(i)
	},
	CoerceInputFunc: coerceBool,
	AstValidator: func(v ast.Value) error {
		switch v.(type) {
		case *ast.BooleanValue:
			return nil
		default:
			return errors.New("invalid value type for Boolean scalar")
		}
	},
}
var DateTime *Scalar = &Scalar{
	Name:        "DateTime",
	Description: "The `DateTime` scalar type represents a DateTime (RFC 3339)",
	CoerceResultFunc: func(i interface{}) (interface{}, error) {
		if m, ok := i.(json.Marshaler); ok {
			return m, nil
		}
		return serializeDateTime(i)
	},
	CoerceInputFunc: unserializeDateTime,
	AstValidator: func(v ast.Value) error {
		switch v.(type) {
		case *ast.StringValue:
			return nil
		default:
			return errors.New("invalid value type for DateTime scalar")
		}
	},
}
var Float *Scalar = &Scalar{
	Name:        "Float",
	Description: "This is the built-in 'Float' scalar type",
	CoerceResultFunc: func(i interface{}) (interface{}, error) {
		if m, ok := i.(json.Marshaler); ok {
			return m, nil
		}
		return coerceFloat(i)
	},
	CoerceInputFunc: coerceFloat,
	AstValidator: func(v ast.Value) error {
		switch v.(type) {
		case *ast.IntValue, *ast.FloatValue:
			return nil
		default:
			return errors.New("invalid value type for Float scalar")
		}
	},
}
var ID *Scalar = &Scalar{
	Name:        "ID",
	Description: "This is the built-in 'ID' scalar type",
	CoerceResultFunc: func(i interface{}) (interface{}, error) {
		switch i := i.(type) {
		case json.Marshaler:
			return i, nil
		case int, int8, int16, int32, uint, uint8, uint16, uint32, string:
			return i, nil
		case []byte:
			return string(i), nil
		case fmt.Stringer:
			return i.String(), nil
		default:
			return fmt.Sprintf("%s", i), nil
		}
	},
	CoerceInputFunc: func(i interface{}) (interface{}, error) {
		switch i := i.(type) {
		case string:
			return i, nil
		default:
			return nil, fmt.Errorf("invalid value for ID scalar, got type: '%T'", i)
		}
	},
	AstValidator: func(v ast.Value) error {
		switch v.(type) {
		case *ast.StringValue, *ast.IntValue:
			return nil
		default:
			return errors.New("invalid value type for ID scalar")
		}
	},
}
var Int *Scalar = &Scalar{
	Name:        "Int",
	Description: "This is the built-in 'Int' scalar type",
	CoerceResultFunc: func(i interface{}) (interface{}, error) {
		switch i := i.(type) {
		case json.Marshaler:
			return i, nil
		default:
			return coerceInt(i)
		}
	},
	CoerceInputFunc: coerceInt,
	AstValidator: func(v ast.Value) error {
		switch v.(type) {
		case *ast.IntValue:
			return nil
		default:
			return errors.New("invalid value type for Int scalar")
		}
	},
}
var String *Scalar = &Scalar{
	Name:        "String",
	Description: "This is the built-in 'String' scalar type",
	CoerceResultFunc: func(i interface{}) (interface{}, error) {
		switch i := i.(type) {
		case json.Marshaler:
			return i, nil
		case string, *string:
			return i, nil
		case []byte:
			return string(i), nil
		case fmt.Stringer:
			return i.String(), nil
		default:
			return fmt.Sprintf("%v", i), nil
		}
	},
	CoerceInputFunc: func(i interface{}) (interface{}, error) {
		switch i := i.(type) {
		case string:
			return i, nil
		default:
			return nil, fmt.Errorf("invalid value for String scalar, got type: '%T'", i)
		}
	},
	AstValidator: func(v ast.Value) error {
		switch v.(type) {
		case *ast.StringValue:
			return nil
		default:
			return errors.New("invalid value type for String scalar")
		}
	},
}

func (*Scalar) CoerceInput added in v0.2.0

func (s *Scalar) CoerceInput(i interface{}) (interface{}, error)

CoerceInput coerces the input value to the type used in execution

func (*Scalar) CoerceResult added in v0.2.0

func (s *Scalar) CoerceResult(i interface{}) (interface{}, error)

CoerceResult coerces a result into the final type

func (*Scalar) GetDescription added in v0.2.0

func (s *Scalar) GetDescription() string

GetDescription shows the description of the scalar

func (*Scalar) GetDirectives added in v0.2.0

func (s *Scalar) GetDirectives() []TypeSystemDirective

GetDirectives returns the directives added to the scalar

func (*Scalar) GetKind added in v0.2.0

func (s *Scalar) GetKind() TypeKind

GetKind returns the kind of the type, ScalarKind

func (*Scalar) GetName added in v0.2.0

func (s *Scalar) GetName() string

GetName returns the name of the scalar

func (*Scalar) String added in v0.5.0

func (s *Scalar) String() string

String implements the fmt.Stringer

type ScalarAstValueValidator added in v0.5.0

type ScalarAstValueValidator func(ast.Value) error

ScalarAstValueValidator validates if the ast value is right

type ScalarDirective added in v0.2.0

type ScalarDirective interface {
	VisitScalar(context.Context, Scalar) *Scalar
}

type Schema

type Schema struct {
	Query           *Object
	Mutation        *Object
	Subscription    *Object
	Directives      TypeSystemDirectives
	AdditionalTypes []Type
	RootValue       interface{}
}

Schema is a graphql schema, a root for the mutations, queries and subscriptions.

A GraphQL service’s collective type system capabilities are referred to as that service’s “schema”. A schema is defined in terms of the types and directives it supports as well as the root operation types for each kind of operation: query, mutation, and subscription; this determines the place in the type system where those operations begin.

func (Schema) SDL added in v0.5.0

func (s Schema) SDL() string

SDL generates an SDL string from your schema

type SchemaDirective added in v0.2.0

type SchemaDirective interface {
	VisitSchema(context.Context, Schema) *Schema
}

type Type

type Type interface {
	GetName() string
	GetDescription() string
	GetKind() TypeKind
	String() string
}

Type represents a Type in the GraphQL Type System

func NewList added in v0.0.2

func NewList(t Type) Type

NewList returns a new List

In every case, you should use NewList function to create a new List, instead of creating on your own.

func NewNonNull added in v0.0.2

func NewNonNull(t Type) Type

NewNonNull function helps create a new Non-Null type It must be used, instead of creating a non null type "manually"

type TypeKind added in v0.2.0

type TypeKind uint

TypeKind shows the kind of a Type

const (
	// ScalarKind is for the Scalars in the GraphQL type system
	ScalarKind TypeKind = iota
	// ObjectKind is for the Object in the GraphQL type system
	ObjectKind
	// InterfaceKind is for the Interface in the GraphQL type system
	InterfaceKind
	// UnionKind is for the Union in the GraphQL type system
	UnionKind
	// EnumKind is for the Enum in the GraphQL type system
	EnumKind
	// InputObjectKind is for the InputObject in the GraphQL type system
	InputObjectKind
	// NonNullKind is for the NonNull in the GraphQL type system
	NonNullKind
	// ListKind is for the List in the GraphQL type system
	ListKind
)

type TypeResolver added in v0.0.3

type TypeResolver func(context.Context, interface{}) *Object

TypeResolver resolves an Interface's return Type

type TypeSystemDirective added in v0.5.0

type TypeSystemDirective interface {
	Directive
	GetValues() map[string]interface{}
}

func Deprecate added in v0.2.0

func Deprecate(reason string) TypeSystemDirective

type TypeSystemDirectives added in v0.5.0

type TypeSystemDirectives []TypeSystemDirective

type Union added in v0.2.0

type Union struct {
	Description  string
	Name         string
	Members      Members
	Directives   TypeSystemDirectives
	TypeResolver TypeResolver
}

Union represents an object that could be one of a list of graphql objects types, but provides for no guaranteed fields between those types. They also differ from interfaces in that Object types declare what interfaces they implement, but are not aware of what unions contain them

func (*Union) GetDescription added in v0.2.0

func (u *Union) GetDescription() string

GetDescription show the description of the Union type

func (*Union) GetDirectives added in v0.2.0

func (u *Union) GetDirectives() []TypeSystemDirective

GetDirectives returns all the directives applied to the Union type

func (*Union) GetKind added in v0.2.0

func (u *Union) GetKind() TypeKind

GetKind returns the kind of the type, UnionType

func (*Union) GetMembers added in v0.2.0

func (u *Union) GetMembers() []Type

GetMembers returns the composite types contained by the union

func (*Union) GetName added in v0.2.0

func (u *Union) GetName() string

GetName show the name of the Union type, "Union"

func (*Union) Resolve added in v0.2.0

func (u *Union) Resolve(ctx context.Context, v interface{}) *Object

Resolve helps decide the executor which contained type to resolve

func (*Union) String added in v0.5.0

func (u *Union) String() string

String implements the fmt.Stringer

type UnionDirective added in v0.2.0

type UnionDirective interface {
	VisitUnion(context.Context, Union) *Union
}

type WrappingType added in v0.2.0

type WrappingType interface {
	Unwrap() Type
}

Directories

Path Synopsis
examples
pkg
federation
The federation package provides the functions, directives and types to create a Schema that's fully capable to work with the Apollo Federation, with Apollo Gateway.
The federation package provides the functions, directives and types to create a Schema that's fully capable to work with the Apollo Federation, with Apollo Gateway.

Jump to

Keyboard shortcuts

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