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 ¶
- type Argument
- type ArgumentDirective
- type Arguments
- type CoerceInputFunc
- type CoerceResultFunc
- type Context
- type CustomError
- type Directive
- type DirectiveLocation
- type Directives
- type Enum
- type EnumDirective
- type EnumValue
- type EnumValueDirective
- type EnumValues
- type Error
- type ErrorLocation
- type Errors
- type Executor
- type ExecutorConfig
- type Extension
- type ExtensionEvent
- type Field
- type FieldDefinitionDirective
- type Fields
- type InputField
- type InputFieldDirective
- type InputFields
- type InputObject
- type InputObjectDirective
- type Interface
- func (i *Interface) GetDescription() string
- func (i *Interface) GetDirectives() []TypeSystemDirective
- func (i *Interface) GetFields() map[string]*Field
- func (i *Interface) GetKind() TypeKind
- func (i *Interface) GetName() string
- func (i *Interface) Resolve(ctx context.Context, v interface{}) *Object
- func (i *Interface) String() string
- type InterfaceDirective
- type Interfaces
- type List
- type Members
- type NonNull
- type Object
- func (o *Object) AddField(name string, f *Field)
- func (o *Object) DoesImplement(i *Interface) bool
- func (o *Object) GetDescription() string
- func (o *Object) GetDirectives() []TypeSystemDirective
- func (o *Object) GetFields() map[string]*Field
- func (o *Object) GetInterfaces() []*Interface
- func (o *Object) GetKind() TypeKind
- func (o *Object) GetName() string
- func (o *Object) String() string
- type ObjectDirective
- type Params
- type Resolver
- type Result
- type Scalar
- func (s *Scalar) CoerceInput(i interface{}) (interface{}, error)
- func (s *Scalar) CoerceResult(i interface{}) (interface{}, error)
- func (s *Scalar) GetDescription() string
- func (s *Scalar) GetDirectives() []TypeSystemDirective
- func (s *Scalar) GetKind() TypeKind
- func (s *Scalar) GetName() string
- func (s *Scalar) String() string
- type ScalarAstValueValidator
- type ScalarDirective
- type Schema
- type SchemaDirective
- type Type
- type TypeKind
- type TypeResolver
- type TypeSystemDirective
- type TypeSystemDirectives
- type Union
- type UnionDirective
- type WrappingType
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Argument ¶
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
IsDefaultValueSet helps to know if the default value was set or not
type ArgumentDirective ¶ added in v0.2.0
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
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
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
type EnumDirective ¶ added in v0.2.0
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
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
IsDeprecated show if the deprecated directive is set for the enum value or not
type EnumValueDirective ¶ added in v0.2.0
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
type ErrorLocation ¶ added in v0.2.0
ErrorLocation represents the location of an error in the query
type Executor ¶ added in v0.2.0
type Executor struct {
// contains filtered or unexported fields
}
func DefaultExecutor ¶ added in v0.2.0
func NewExecutor ¶ added in v0.2.0
func NewExecutor(c ExecutorConfig) *Executor
type ExecutorConfig ¶ added in v0.2.0
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
GetArguments of the field
func (*Field) GetDescription ¶ added in v0.2.0
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) IsDeprecated ¶ added in v0.2.0
IsDeprecated returns if the field is depricated
type FieldDefinitionDirective ¶ added in v0.2.0
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
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
GetFields returns all the fields that can be implemented on the interface
type InterfaceDirective ¶ added in v0.2.0
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
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
GetDescription shows the description of the type
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
NonNull type from the GraphQL type system
func (*NonNull) GetDescription ¶ added in v0.2.0
GetDescription returns the description 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) DoesImplement ¶ added in v0.2.0
DoesImplement helps decide if the object implements an interface or not
func (*Object) GetDescription ¶ added in v0.2.0
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) GetInterfaces ¶ added in v0.2.0
GetInterfaces returns all the interfaces that the object implements
type ObjectDirective ¶ added in v0.2.0
type Resolver ¶ added in v0.2.0
Resolver function that can resolve a field using the Context from the executor
type 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
CoerceInput coerces the input value to the type used in execution
func (*Scalar) CoerceResult ¶ added in v0.2.0
CoerceResult coerces a result into the final type
func (*Scalar) GetDescription ¶ added in v0.2.0
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
type ScalarAstValueValidator ¶ added in v0.5.0
ScalarAstValueValidator validates if the ast value is right
type ScalarDirective ¶ added in v0.2.0
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.
type SchemaDirective ¶ added in v0.2.0
type Type ¶
Type represents a Type in the GraphQL Type System
func NewList ¶ added in v0.0.2
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
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
TypeResolver resolves an Interface's return Type
type TypeSystemDirective ¶ added in v0.5.0
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
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) GetMembers ¶ added in v0.2.0
GetMembers returns the composite types contained by the union
type UnionDirective ¶ added in v0.2.0
type WrappingType ¶ added in v0.2.0
type WrappingType interface {
Unwrap() Type
}
Source Files ¶
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. |