gqlx

package
v0.17.3 Latest Latest
Warning

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

Go to latest
Published: Jul 31, 2026 License: Apache-2.0 Imports: 21 Imported by: 0

Documentation

Overview

Package gqlx is a self-contained GraphQL engine used by apic-generated services. It implements the full request pipeline in the standard library: a lexer and parser producing an AST, a schema model with scalar/object/field descriptors and resolver functions, query validation, and an executor that runs queries and mutations. An http.Handler serves GraphQL over GET and POST (including JSON batch requests), and subscriptions are delivered over a RFC 6455 WebSocket transport whose framing layer is inlined here (subscription.go) and is independent of pkg/wsx. Security limits are first-class and fail-closed: bounded query size, depth, complexity, batch size, and alias counts; introspection (__schema/__type) is denied by default; and parsed, validated documents are cached in a bounded LRU sitting behind the size gate.

Index

Constants

View Source
const DefaultMaxResolvedFields = 10000

DefaultMaxResolvedFields is the resolved-field budget applied when ExecuteOptions.MaxResolvedFields is zero. Generous: a legitimate query under the default validation limits (depth 10, complexity 100) resolves orders of magnitude fewer fields. PERF-0075.

Variables

View Source
var (
	ErrDepthExceeded      = errors.New("gqlx: query depth exceeds configured limit")
	ErrComplexityExceeded = errors.New("gqlx: query complexity exceeds configured limit")
	ErrAliasLimitExceeded = errors.New("gqlx: alias count exceeds configured limit")
	ErrIntrospection      = errors.New("gqlx: introspection disabled")
	ErrBatchLimitExceeded = errors.New("gqlx: batch size exceeds configured limit")
	ErrResolverTimeout    = errors.New("gqlx: resolver execution timed out")
	ErrFragmentCycle      = errors.New("gqlx: fragment cycle detected")
	ErrQueryTooLarge      = errors.New("gqlx: query body exceeds configured size")
	ErrAuthRequired       = errors.New("gqlx: authentication required")
	ErrRateLimited        = errors.New("gqlx: rate limit exceeded")
	ErrInvalidConfig      = errors.New("gqlx: invalid configuration")
	ErrFieldNotFound      = errors.New("gqlx: field not found in schema")
	ErrInvalidArgument    = errors.New("gqlx: invalid argument")
	ErrVariableNotDefined = errors.New("gqlx: variable referenced but not defined")
	ErrVariableUnused     = errors.New("gqlx: variable defined but not used")
	// ErrResolvedFieldLimit trips when a single execution resolves more
	// fields than the configured budget permits — ExecuteOptions.MaxResolvedFields
	// directly, or HandlerOptions.MaxResolvedFields for handler-served
	// requests (PERF-0075). It is the executor's own defense against
	// fragment bombs reaching execution with the validator's complexity
	// limits disabled. The GQLError surfacing it wraps this sentinel, so
	// errors.Is(respErr, ErrResolvedFieldLimit) holds.
	ErrResolvedFieldLimit = errors.New("gqlx: resolved field count exceeds configured limit")
	// ErrMutationOverGET trips when a client submits a mutation or
	// subscription operation via HTTP GET (GAP-0022). GET requests are
	// idempotent/cacheable by convention and, in a cookie-authenticated
	// deployment, reachable via simple top-level cross-site navigation
	// even under SameSite=Lax — so a state-changing operation permitted
	// over GET is a CSRF primitive. The generator additionally hardcodes
	// AllowGET: false in front of RegisterGeneratedGQL (see
	// cmd/apic/templates/server_lib.go.tmpl) so generated servers never
	// route GET here at all, but Handler is itself an exported package
	// usable directly (NewHandler wired by hand), so the invariant is
	// enforced here too, at the library layer.
	ErrMutationOverGET = errors.New("gqlx: mutation and subscription operations are not allowed over GET")
)

Sentinel errors for GraphQL runtime. Kept at package level per repo conventions. Messages use a lowercase, package-prefixed, diagnostic form so log output reads naturally; errors.Is callers should rely on pointer equality rather than substring matching of Error().

View Source
var (
	TypeString  = &ScalarType{Name: "String"}
	TypeInt     = &ScalarType{Name: "Int"}
	TypeFloat   = &ScalarType{Name: "Float"}
	TypeBoolean = &ScalarType{Name: "Boolean"}
	TypeID      = &ScalarType{Name: "ID"}
)

Built-in scalar types per the GraphQL specification.

View Source
var BuiltinScalarCoercers = map[string]*ScalarType{
	"datetime": ScalarDateTime,
	"uuid":     ScalarUUID,
	"json":     ScalarJSON,
}

BuiltinScalarCoercers exposes the built-in custom scalars by their short coercer-id so generated code can register them from config without reflecting on Go variable names.

View Source
var ErrWSFrameTooLarge = errors.New("gqlx: websocket frame exceeds configured size")

ErrWSFrameTooLarge is returned by the in-package WebSocket frame reader when an inbound frame exceeds [maxWSFrameBytes]. The reader is independent of pkg/wsx's framing, so the sentinel lives here to keep gqlx self-contained.

View Source
var ScalarDateTime = &ScalarType{
	Name: "DateTime",
	Coerce: func(v any) (any, error) {
		switch x := v.(type) {
		case nil:
			return nil, nil
		case time.Time:
			return x, nil
		case *time.Time:
			if x == nil {
				return nil, nil
			}
			return *x, nil
		case string:
			if t, err := time.Parse(time.RFC3339Nano, x); err == nil {
				return t, nil
			}
			if t, err := time.Parse(time.RFC3339, x); err == nil {
				return t, nil
			}
			return nil, fmt.Errorf("gqlx: DateTime must be RFC3339, got %q", x)
		default:
			return nil, fmt.Errorf("gqlx: DateTime cannot accept %T", v)
		}
	},
}

ScalarDateTime coerces RFC3339 / RFC3339Nano strings (and *time.Time / time.Time values) to time.Time. It is intentionally strict: malformed strings produce an error so they are rejected at validation time rather than producing garbage downstream.

View Source
var ScalarJSON = &ScalarType{
	Name: "JSON",
	Coerce: func(v any) (any, error) {
		return v, nil
	},
}

ScalarJSON accepts any JSON-shaped value and passes it through. Use for free-form structured payloads where the schema does not need to enforce shape (audit blobs, vendor extensions, etc.).

View Source
var ScalarUUID = &ScalarType{
	Name: "UUID",
	Coerce: func(v any) (any, error) {
		s, ok := v.(string)
		if !ok {
			return nil, fmt.Errorf("gqlx: UUID must be a string, got %T", v)
		}
		if !isUUID(s) {
			return nil, fmt.Errorf("gqlx: UUID malformed: %q", s)
		}
		return s, nil
	},
}

ScalarUUID coerces RFC4122 UUID strings. The check is purely syntactic (length + hyphen layout + hex characters) so the package keeps zero runtime deps — callers that want canonicalization can still wrap this with their own scalar.

Functions

func ContextWithRequest

func ContextWithRequest(ctx context.Context, r *http.Request) context.Context

ContextWithRequest stores the active HTTP request in a context for resolver auth checks.

func RequestFromContext

func RequestFromContext(ctx context.Context) (*http.Request, bool)

RequestFromContext retrieves the active HTTP request when present.

func Validate

func Validate(doc *Document, schema *Schema, opts ValidateOptions) error

Validate checks a parsed GraphQL document against a schema for security and correctness. It validates all operations in the document.

Types

type ArgDef

type ArgDef struct {
	Name     string
	Type     GQLType
	Default  any
	Required bool
}

ArgDef describes a single argument accepted by a field.

type Argument

type Argument struct {
	Name  string
	Value Value
}

Argument is a key-value pair passed to a field or directive.

type AuthFunc

type AuthFunc func(ctx context.Context) string

AuthFunc extracts an auth credential from the context. Return a non-empty string if the credential is present and valid.

type BoolValue

type BoolValue struct{ V bool }

BoolValue holds a GraphQL boolean literal.

type Directive

type Directive struct {
	Name      string
	Arguments []*Argument
}

Directive represents an @-prefixed directive application.

type Document

type Document struct {
	Operations []*Operation
	Fragments  []*FragmentDef
}

Document is the top-level AST node produced by the parser.

func Parse

func Parse(input string) (*Document, error)

Parse lexes the input GraphQL document string and builds an AST using the historical defaults (introspection root fields rejected). Callers who need to flip the introspection knob should use ParseWithOptions.

func ParseWithOptions

func ParseWithOptions(input string, opts ParseOptions) (*Document, error)

ParseWithOptions is the option-aware form of Parse.

type EnumType

type EnumType struct {
	Name        string
	Description string
	// contains filtered or unexported fields
}

EnumType represents a GraphQL enum. Like ObjectType, enum values are stored in insertion order for deterministic schema emission while also supporting O(1) lookup by name.

func NewEnumType

func NewEnumType(name string) *EnumType

NewEnumType creates a new EnumType with the given name and initialized internal storage.

func (*EnumType) AddValue

func (e *EnumType) AddValue(name, desc string)

AddValue registers an enum variant under the given name. Re-adding a name replaces its definition while preserving insertion order.

func (*EnumType) TypeName

func (e *EnumType) TypeName() string

TypeName returns the enum's name as written in the schema.

func (*EnumType) Value

func (e *EnumType) Value(name string) (EnumValueDef, bool)

Value looks up an enum variant by name. Returns the definition and true if found, or a zero EnumValueDef and false otherwise.

func (*EnumType) Values

func (e *EnumType) Values() []EnumValueDef

Values returns variant definitions in insertion order. The returned slice is a copy and may be mutated by the caller.

type EnumValue

type EnumValue struct{ V string }

EnumValue holds a GraphQL enum literal.

type EnumValueDef

type EnumValueDef struct {
	Name        string
	Description string
	Deprecation string
}

EnumValueDef is one variant within an EnumType.

type ExecuteOptions

type ExecuteOptions struct {
	Validate           ValidateOptions
	AllowIntrospection bool

	// MaxResolvedFields bounds the TOTAL number of fields the executor
	// resolves for one operation, counting every field reached through
	// fragment spreads, inline fragments, nested selections, and list
	// elements. It is the executor's own defense-in-depth against
	// fragment bombs: the validator already memoizes fragment cost
	// (PERF-0064), but a caller that disables the complexity limits can
	// still hand the executor a document whose expansion is exponential
	// in document size (the executor re-walks fragment selections per
	// spread site — memoizing results would be wrong, the result differs
	// per spread site). When the budget is exhausted execution halts and
	// the response carries a single ErrResolvedFieldLimit error.
	// PERF-0075.
	//
	// Zero applies DefaultMaxResolvedFields; a negative value disables
	// the budget.
	MaxResolvedFields int
}

ExecuteOptions tunes Execute's behavior beyond the historical ValidateOptions surface. The zero value preserves Execute's original contract; in particular, AllowIntrospection defaults to false so a rebuild does not unintentionally expose a protected schema.

type Field

type Field struct {
	Alias      string
	Name       string
	Arguments  []*Argument
	Directives []*Directive
	Selections []Selection
}

Field is a single field selection, optionally aliased and nested.

type FieldDef

type FieldDef struct {
	Type        GQLType
	Args        []ArgDef
	Description string
	Auth        string
	RateLimit   int
	Resolve     ResolverFunc
	Subscribe   SubscribeFunc
	// contains filtered or unexported fields
}

FieldDef describes a single field on an ObjectType, including its return type, arguments, metadata, and resolver function.

type FloatValue

type FloatValue struct{ V float64 }

FloatValue holds a GraphQL float literal.

type FragmentDef

type FragmentDef struct {
	Name          string
	TypeCondition string
	Directives    []*Directive
	Selections    []Selection
}

FragmentDef is a named fragment definition.

type FragmentSpread

type FragmentSpread struct {
	Name       string
	Directives []*Directive
}

FragmentSpread references a named fragment definition.

type GQLError

type GQLError struct {
	Message    string         `json:"message"`
	Locations  []Location     `json:"locations,omitempty"`
	Path       []any          `json:"path,omitempty"`
	Extensions map[string]any `json:"extensions,omitempty"`
	// contains filtered or unexported fields
}

GQLError represents a single error in a GraphQL response per the spec.

func (*GQLError) Error

func (e *GQLError) Error() string

Error implements the error interface.

func (*GQLError) Unwrap

func (e *GQLError) Unwrap() error

Unwrap exposes the optional wrapped sentinel for errors.Is/errors.As. It is nil-safe: a GQLError constructed without a wrapped error returns nil and terminates the unwrap chain.

type GQLType

type GQLType interface {
	TypeName() string
	// contains filtered or unexported methods
}

GQLType is the interface implemented by all GraphQL type descriptors. The unexported marker method prevents external packages from implementing the interface.

type Handler

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

Handler serves GraphQL queries over HTTP GET and POST. It implements http.Handler and supports single requests as well as batch requests (JSON arrays).

func NewHandler

func NewHandler(schema *Schema, opts HandlerOptions) *Handler

NewHandler creates a Handler for the given schema, applying sensible defaults for any zero-valued option fields.

func (*Handler) ServeHTTP

func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP dispatches GraphQL requests. GET requests read query parameters; POST requests read a JSON body. Batch requests (JSON arrays) are supported for POST only.

type HandlerOptions

type HandlerOptions struct {
	Timeout       time.Duration
	MaxQueryBytes int
	MaxBatchSize  int
	MaxDepth      int
	MaxComplexity int
	MaxAliases    int

	// AllowIntrospection, when true, lets the handler accept root-level
	// __schema and __type selections and resolves them against the
	// loaded Schema. Defaults to false so an accidental rebuild does not
	// expose a previously-protected surface. Pair with an admin-only
	// auth check on the route.
	AllowIntrospection bool

	// MaxResolvedFields bounds the TOTAL number of fields the executor
	// may resolve for a single handler-served request, mirroring
	// ExecuteOptions.MaxResolvedFields (PERF-0075). Zero applies
	// DefaultMaxResolvedFields; a negative value disables the budget.
	MaxResolvedFields int

	// DocCacheSize bounds the per-Handler LRU cache of parsed+validated
	// documents keyed by raw query string (PERF-0058). The zero value
	// selects the default of 256 entries; a negative value disables the
	// cache so every request re-parses and re-validates. The MaxQueryBytes
	// gate runs in front of the cache, so cache keys are bounded and an
	// attacker streaming unique oversized queries cannot grow the cache.
	DocCacheSize int

	// MaxBatchConcurrency bounds the number of batch elements handleBatch
	// executes concurrently (N-10), mirroring pkg/mcpx's
	// batchMaxConcurrency semaphore for its own parallel tool-batch
	// dispatch. MaxBatchSize alone only bounds the TOTAL element count
	// per request, not how many run at once — every element previously
	// got its own unbounded goroutine, so an operator raising
	// MaxBatchSize (e.g. for a legitimately large trusted-client batch)
	// also raised the in-flight goroutine/resolver-concurrency ceiling by
	// the same amount with no separate control. A value <= 0 selects the
	// default of 8 (matching mcpx).
	MaxBatchConcurrency int
}

HandlerOptions configures the GraphQL HTTP handler's security and operational limits.

type InlineFragment

type InlineFragment struct {
	TypeCondition string
	Directives    []*Directive
	Selections    []Selection
}

InlineFragment is an anonymous fragment with an optional type condition.

type InputFieldDef

type InputFieldDef struct {
	Type     GQLType
	Required bool
	Default  any
}

InputFieldDef describes one field on an InputObjectType.

type InputObjectType

type InputObjectType struct {
	Name        string
	Description string
	// contains filtered or unexported fields
}

InputObjectType represents a GraphQL input object. Field types must be scalar, enum, list-of-input, or another input object — i.e. they may not point at output ObjectTypes. The type enforcement is not done at construction time; the validator and executor surface mismatches.

func NewInputObjectType

func NewInputObjectType(name string) *InputObjectType

NewInputObjectType creates an InputObjectType with the given name and initialized internal storage.

func (*InputObjectType) AddField

func (o *InputObjectType) AddField(name string, def InputFieldDef)

AddField registers an input field under the given name. Re-adding a name replaces its definition but preserves insertion order.

func (*InputObjectType) Field

func (o *InputObjectType) Field(name string) (InputFieldDef, bool)

Field looks up an input field by name.

func (*InputObjectType) Fields

func (o *InputObjectType) Fields() []namedInputField

Fields returns input field definitions in insertion order.

func (*InputObjectType) TypeName

func (o *InputObjectType) TypeName() string

TypeName returns the input object's name as written in the schema.

type IntValue

type IntValue struct{ V int64 }

IntValue holds a GraphQL integer literal.

type ListType

type ListType struct {
	Elem GQLType
}

ListType wraps another GQLType to represent a GraphQL list ([T]).

func ListOf

func ListOf(t GQLType) *ListType

ListOf wraps a GQLType in a ListType.

func (*ListType) TypeName

func (l *ListType) TypeName() string

type ListValue

type ListValue struct{ Values []Value }

ListValue holds a GraphQL list literal.

type Location

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

Location identifies a position in the source query text.

type NonNullType

type NonNullType struct {
	Elem GQLType
}

NonNullType wraps another GQLType to represent a non-null GraphQL type (T!).

func NonNullOf

func NonNullOf(t GQLType) *NonNullType

NonNullOf wraps a GQLType in a NonNullType.

func (*NonNullType) TypeName

func (n *NonNullType) TypeName() string

type NullValue

type NullValue struct{}

NullValue represents the GraphQL null literal.

type ObjectField

type ObjectField struct {
	Name  string
	Value Value
}

ObjectField is a single field inside an ObjectValue.

type ObjectType

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

ObjectType represents a GraphQL object type with named fields. Fields maintain insertion order for deterministic output while also supporting O(1) lookup by name.

func NewObjectType

func NewObjectType(name string) *ObjectType

NewObjectType creates a new ObjectType with the given name and initialized internal storage.

func (*ObjectType) AddField

func (o *ObjectType) AddField(name string, f FieldDef)

AddField registers a field definition under the given name. If a field with the same name already exists, it is replaced but the insertion position is preserved. The field's argument index is precomputed here (once per registration) so resolver-time coercion avoids rebuilding it on every request (PERF-0061).

func (*ObjectType) Field

func (o *ObjectType) Field(name string) (FieldDef, bool)

Field looks up a field by name. Returns the definition and true if found, or a zero FieldDef and false otherwise.

func (*ObjectType) Fields

func (o *ObjectType) Fields() []string

Fields returns field names in insertion order.

func (*ObjectType) TypeName

func (o *ObjectType) TypeName() string

type ObjectValue

type ObjectValue struct{ Fields []*ObjectField }

ObjectValue holds a GraphQL input object literal.

type Operation

type Operation struct {
	Type       OperationType
	Name       string
	Variables  []*VariableDef
	Directives []*Directive
	Selections []Selection
}

Operation represents a single query, mutation, or subscription.

type OperationType

type OperationType int

OperationType enumerates the three root operation kinds in GraphQL.

const (
	OperationQuery OperationType = iota
	OperationMutation
	OperationSubscription
)

type ParseOptions

type ParseOptions struct {
	// AllowIntrospection, when true, lets __schema and __type appear as
	// root-level selections. Even with this disabled __typename remains
	// allowed in nested selections so client tooling that depends on
	// type-tagging continues to work.
	AllowIntrospection bool

	// MaxDepth caps the structural nesting depth (selection sets + list/object
	// argument values) the recursive-descent parser will descend before
	// aborting with ErrDepthExceeded. This is a DEFENSE against stack-overflow
	// DoS: the validator's MaxDepth runs only AFTER a full parse, so without
	// this a deeply-nested document crashes the process during parsing (a Go
	// stack overflow is a fatal throw that recover() cannot catch). 0 selects
	// defaultParseMaxDepth. Counts both selection and value nesting, so it is
	// intentionally larger than the selection-only validation MaxDepth. R2-1.
	MaxDepth int
}

ParseOptions tunes the parser's behavior. The zero value preserves the historical Parse() contract — introspection root fields (__schema, __type) are rejected so a misconfigured server cannot leak its schema.

type ResolverFunc

type ResolverFunc func(ctx context.Context, args map[string]any) (any, error)

ResolverFunc is the signature for field resolver functions. It receives a context and a map of parsed arguments, returning the resolved value or an error.

type Response

type Response struct {
	Data   any         `json:"data"`
	Errors []*GQLError `json:"errors,omitempty"`
}

Response is the top-level JSON envelope for GraphQL responses.

func Execute

func Execute(ctx context.Context, schema *Schema, query string, variables map[string]any, operationName string, timeout time.Duration, vopts ...ValidateOptions) *Response

Execute parses, validates, and executes a GraphQL query against the given schema. It never returns a Go error; all errors are wrapped in the Response.Errors slice. Variables supplies runtime variable values, operationName selects a specific operation when the document contains more than one, and timeout limits individual resolver execution time. An optional ValidateOptions may be provided; when absent sensible defaults are used.

func ExecuteWithOptions

func ExecuteWithOptions(ctx context.Context, schema *Schema, query string, variables map[string]any, operationName string, timeout time.Duration, eopts ExecuteOptions) *Response

ExecuteWithOptions is the option-aware form of Execute. It is wired from HandlerOptions so callers can opt in to introspection without changing the historical Execute signature.

type ScalarType

type ScalarType struct {
	Name   string
	Coerce func(any) (any, error)
}

ScalarType represents a built-in or custom GraphQL scalar.

Coerce is optional. When set, it is invoked by the executor whenever a value at this scalar position is observed (resolver argument coming from a variable, literal during validation). A nil Coerce keeps the historical pass-through behavior so the five built-in scalars (String/Int/Float/Boolean/ID) remain wire-compatible without changes.

func (*ScalarType) TypeName

func (s *ScalarType) TypeName() string

type Schema

type Schema struct {
	Query        *ObjectType
	Mutation     *ObjectType
	Subscription *ObjectType

	// AuthFunc is called to enforce field-level auth. When a FieldDef has
	// a non-empty Auth string the executor calls AuthFunc; if it returns
	// "" the field is rejected with ErrAuthRequired.
	AuthFunc AuthFunc
}

Schema holds the three root operation types for a GraphQL service.

func NewSchema

func NewSchema() *Schema

NewSchema creates a Schema with initialized root types for Query, Mutation, and Subscription.

type Selection

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

Selection is implemented by Field, FragmentSpread, and InlineFragment.

type StringValue

type StringValue struct{ V string }

StringValue holds a GraphQL string literal.

type SubscribeFunc

type SubscribeFunc func(ctx context.Context, args map[string]any) (<-chan any, error)

SubscribeFunc is the signature for subscription resolver functions. It returns a channel that emits values for as long as the subscription is active. Closing the channel ends the subscription.

type SubscriptionHandler

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

SubscriptionHandler manages subscription lifecycle over WebSocket using the graphql-transport-ws protocol (https://github.com/enisdenjo/graphql-ws).

N-09: one handler per connection. HandleConn is meant to be called exactly once per *SubscriptionHandler — the generated code follows this by constructing a fresh handler for every upgraded connection (cmd/apic/templates/gql_handlers.go.tmpl). Calling HandleConn again on an instance that already served a connection (sequentially or concurrently) is defended against (see HandleConn) but is not the intended usage: a dedicated handler per connection keeps the subs/conn/bw state trivially scoped and avoids relying on that defense at all.

func NewSubscriptionHandler

func NewSubscriptionHandler(schema *Schema, opts SubscriptionOptions) *SubscriptionHandler

NewSubscriptionHandler creates a subscription handler.

func (*SubscriptionHandler) HandleConn

func (h *SubscriptionHandler) HandleConn(c net.Conn, req *http.Request)

HandleConn runs the graphql-transport-ws protocol over a raw net.Conn. The caller is responsible for completing the HTTP-to-WebSocket upgrade before passing the connection. HandleConn blocks until the connection is closed or an unrecoverable error occurs.

N-09: intended to be called once per handler (see the one-handler-per- connection contract on SubscriptionHandler). As defense in depth against a caller reusing an instance, any subscriptions still tracked from a PRIOR HandleConn call are cancelled here before the registry is reset — otherwise h.subs = make(...) below would silently orphan them: their stream goroutines (streamSubscription) delete from whatever h.subs currently points to, which after this reassignment is a different, freshly-empty map, so their contexts/goroutines would never be cancelled and would leak until (if ever) their channel closes on its own.

type SubscriptionOptions

type SubscriptionOptions struct {
	MaxSubscriptions int
	ValidateOptions  ValidateOptions
	// IdleTimeout bounds how long the read loop will block waiting for the
	// next client frame. Without it a connected-but-idle (or slow-trickle)
	// client holds the read goroutine and socket forever — a slow-loris DoS,
	// since the GraphQL-WS path reads the raw net.Conn directly. 0 selects
	// defaultSubscriptionIdleTimeout. R2-2.
	IdleTimeout time.Duration
}

SubscriptionOptions configures the subscription handler.

type Token

type Token struct {
	Kind  TokenKind
	Value string
	Line  int
	Col   int
}

Token represents a single lexical token from a GraphQL document.

func Lex

func Lex(input string) ([]Token, error)

Lex tokenizes a GraphQL document string and returns the token slice. The final token is always TokEOF. Returns an error for malformed input.

func (Token) String

func (t Token) String() string

String returns a debug representation of the token.

type TokenKind

type TokenKind int

TokenKind classifies each token produced by the lexer.

const (
	TokEOF      TokenKind = iota // end of input
	TokName                      // identifier: [_A-Za-z][_0-9A-Za-z]*
	TokInt                       // integer literal
	TokFloat                     // float literal
	TokString                    // string or block string literal
	TokLBrace                    // {
	TokRBrace                    // }
	TokLParen                    // (
	TokRParen                    // )
	TokLBracket                  // [
	TokRBracket                  // ]
	TokColon                     // :
	TokBang                      // !
	TokDollar                    // $
	TokAt                        // @
	TokEquals                    // =
	TokSpread                    // ...
	TokPipe                      // |
)

func (TokenKind) String

func (k TokenKind) String() string

String returns the human-readable name for the token kind.

type TypeRef

type TypeRef struct {
	Name    string
	Elem    *TypeRef
	NonNull bool
}

TypeRef models named, list, and non-null type references.

type ValidateOptions

type ValidateOptions struct {
	MaxDepth      int
	MaxComplexity int
	MaxAliases    int
}

ValidateOptions controls the security limits enforced during validation.

type Value

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

Value is implemented by all GraphQL value literal types.

type VariableDef

type VariableDef struct {
	Name    string
	Type    TypeRef
	Default Value
}

VariableDef captures a variable declaration inside an operation.

type VariableValue

type VariableValue struct{ Name string }

VariableValue references a variable by name.

Jump to

Keyboard shortcuts

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