Documentation ¶
Index ¶
- Constants
- Variables
- func AddError(ctx context.Context, err error)
- func AddErrorf(ctx context.Context, format string, args ...any)
- func BuildUnmarshalerMap(unmarshaler ...any) map[reflect.Type]reflect.Value
- func CoerceList(v any) []any
- func CollectAllFields(ctx context.Context) []string
- func DefaultErrorPresenter(ctx context.Context, err error) *gqlerror.Error
- func DefaultRecover(ctx context.Context, err any) error
- func ErrorOnPath(ctx context.Context, err error) error
- func GetErrors(ctx context.Context) gqlerror.List
- func GetExtension(ctx context.Context, name string) any
- func GetExtensions(ctx context.Context) map[string]any
- func GetFieldErrors(ctx context.Context, rctx *FieldContext) gqlerror.List
- func GetPath(ctx context.Context) ast.Path
- func GetStartTime(ctx context.Context) time.Time
- func HasFieldError(ctx context.Context, rctx *FieldContext) bool
- func HasOperationContext(ctx context.Context) bool
- func Recover(ctx context.Context, err any) (userMessage error)
- func RegisterExtension(ctx context.Context, key string, value any)
- func StartOperationTrace(ctx context.Context) context.Context
- func UnmarshalAny(v any) (any, error)
- func UnmarshalBoolean(v any) (bool, error)
- func UnmarshalDuration(v any) (time.Duration, error)
- func UnmarshalFloat(v any) (float64, error)
- func UnmarshalFloatContext(ctx context.Context, v any) (float64, error)
- func UnmarshalID(v any) (string, error)
- func UnmarshalInputFromContext(ctx context.Context, raw, v any) error
- func UnmarshalInt(v any) (int, error)
- func UnmarshalInt32(v any) (int32, error)
- func UnmarshalInt64(v any) (int64, error)
- func UnmarshalIntID(v any) (int, error)
- func UnmarshalMap(v interface{}) (map[string]interface{}, error)
- func UnmarshalString(v any) (string, error)
- func UnmarshalTime(v any) (time.Time, error)
- func UnmarshalUUID(v any) (uuid.UUID, error)
- func UnmarshalUint(v any) (uint, error)
- func UnmarshalUint32(v any) (uint32, error)
- func UnmarshalUint64(v any) (uint64, error)
- func UnmarshalUintID(v any) (uint, error)
- func WithFieldContext(ctx context.Context, rc *FieldContext) context.Context
- func WithFreshResponseContext(ctx context.Context) context.Context
- func WithOperationContext(ctx context.Context, opCtx *OperationContext) context.Context
- func WithPathContext(ctx context.Context, fic *PathContext) context.Context
- func WithResponseContext(ctx context.Context, presenterFunc ErrorPresenterFunc, recoverFunc RecoverFunc) context.Context
- func WithRootFieldContext(ctx context.Context, rc *RootFieldContext) context.Context
- func WithUnmarshalerMap(ctx context.Context, maps map[reflect.Type]reflect.Value) context.Context
- type Array
- type Cache
- type CollectedField
- type ContextMarshaler
- type ContextUnmarshaler
- type ContextWriterFunc
- type Deferrable
- type DeferredGroup
- type DeferredResult
- type ErrorPresenterFunc
- type ExecutableSchema
- type ExecutableSchemaMock
- func (mock *ExecutableSchemaMock) Complexity(typeName string, fieldName string, childComplexity int, args map[string]any) (int, bool)
- func (mock *ExecutableSchemaMock) ComplexityCalls() []struct{ ... }
- func (mock *ExecutableSchemaMock) Exec(ctx context.Context) ResponseHandler
- func (mock *ExecutableSchemaMock) ExecCalls() []struct{ ... }
- func (mock *ExecutableSchemaMock) Schema() *ast.Schema
- func (mock *ExecutableSchemaMock) SchemaCalls() []struct{}
- type FieldContext
- type FieldInterceptor
- type FieldMiddleware
- type FieldSet
- type FieldStats
- type GraphExecutor
- type HandlerExtension
- type MapCache
- type Marshaler
- func MarshalAny(v any) Marshaler
- func MarshalBoolean(b bool) Marshaler
- func MarshalDuration(d time.Duration) Marshaler
- func MarshalFloat(f float64) Marshaler
- func MarshalID(s string) Marshaler
- func MarshalInt(i int) Marshaler
- func MarshalInt32(i int32) Marshaler
- func MarshalInt64(i int64) Marshaler
- func MarshalIntID(i int) Marshaler
- func MarshalMap(val map[string]interface{}) Marshaler
- func MarshalString(s string) Marshaler
- func MarshalTime(t time.Time) Marshaler
- func MarshalUUID(id uuid.UUID) Marshaler
- func MarshalUint(i uint) Marshaler
- func MarshalUint32(i uint32) Marshaler
- func MarshalUint64(i uint64) Marshaler
- func MarshalUintID(i uint) Marshaler
- func MarshalUpload(f Upload) Marshaler
- func WrapContextMarshaler(ctx context.Context, m ContextMarshaler) Marshaler
- type Mutation
- type NoCache
- type Omittable
- type OperationContext
- type OperationContextMutator
- type OperationHandler
- type OperationInterceptor
- type OperationMiddleware
- type OperationParameterMutator
- type PathContext
- type Query
- type RawParams
- type RecoverFunc
- type RequestContextdeprecated
- type Resolver
- type ResolverContextdeprecated
- type Response
- type ResponseHandler
- type ResponseInterceptor
- type ResponseMiddleware
- type RootFieldContext
- type RootFieldInterceptor
- type RootFieldMiddleware
- type RootResolver
- type Stats
- type Status
- type Subscription
- type TraceTiming
- type Transport
- type Unmarshaler
- type Upload
- type WriterFunc
Constants ¶
const Version = "v0.17.56"
Variables ¶
var ( Null = &lit{nullLit} True = &lit{trueLit} False = &lit{falseLit} )
var Now = time.Now
Now is time.Now, except in tests. Then it can be whatever you want it to be.
Functions ¶
func AddError ¶
AddError sends an error to the client, first passing it through the error presenter.
func AddErrorf ¶
AddErrorf writes a formatted error to the client, first passing it through the error presenter.
func BuildUnmarshalerMap ¶ added in v0.17.5
BuildUnmarshalerMap returns a map of unmarshal functions of the ExecutableContext to use with the WithUnmarshalerMap function.
func CoerceList ¶ added in v0.15.0
CoerceList applies coercion from a single value to a list.
func CollectAllFields ¶ added in v0.8.0
CollectAllFields returns a slice of all GraphQL field names that were selected for the current resolver context. The slice will contain the unique set of all field names requested regardless of fragment type conditions.
func DefaultErrorPresenter ¶
func GetExtensions ¶ added in v0.11.0
GetExtensions returns any extensions registered in the current result context
func GetFieldErrors ¶ added in v0.11.0
func GetFieldErrors(ctx context.Context, rctx *FieldContext) gqlerror.List
GetFieldErrors returns a list of errors that occurred in the given field
func GetStartTime ¶ added in v0.11.0
GetStartTime should only be called by the handler package, it will be set into request context as Stats.Start
func HasFieldError ¶ added in v0.11.0
func HasFieldError(ctx context.Context, rctx *FieldContext) bool
HasFieldError returns true if the given field has already errored
func HasOperationContext ¶ added in v0.11.2
HasOperationContext checks if the given context is part of an ongoing operation
Some errors can happen outside of an operation, eg json unmarshal errors.
func RegisterExtension ¶ added in v0.11.0
RegisterExtension allows you to add a new extension into the graphql response
func StartOperationTrace ¶ added in v0.11.0
StartOperationTrace captures the current time and stores it in context. This will eventually be added to request context but we want to grab it as soon as possible. For transports that can only handle a single graphql query per http requests you don't need to call this at all, the server will do it for you. For transports that handle multiple (eg batching, subscriptions) this should be called before decoding each request.
func UnmarshalAny ¶ added in v0.9.0
func UnmarshalBoolean ¶
func UnmarshalDuration ¶ added in v0.17.39
UnmarshalDuration returns the duration from a string in ISO8601 format
func UnmarshalFloat ¶
func UnmarshalFloatContext ¶ added in v0.15.0
func UnmarshalID ¶
func UnmarshalInputFromContext ¶ added in v0.17.5
UnmarshalInputFromContext allows unmarshaling input object from a context.
func UnmarshalInt ¶
func UnmarshalInt32 ¶ added in v0.8.0
func UnmarshalInt64 ¶ added in v0.8.0
func UnmarshalIntID ¶ added in v0.8.0
func UnmarshalMap ¶
func UnmarshalString ¶
func UnmarshalUint ¶ added in v0.14.0
func UnmarshalUint32 ¶ added in v0.14.0
func UnmarshalUint64 ¶ added in v0.14.0
func UnmarshalUintID ¶ added in v0.17.46
func WithFieldContext ¶ added in v0.11.0
func WithFieldContext(ctx context.Context, rc *FieldContext) context.Context
func WithFreshResponseContext ¶ added in v0.17.32
func WithOperationContext ¶ added in v0.11.0
func WithOperationContext(ctx context.Context, opCtx *OperationContext) context.Context
func WithPathContext ¶ added in v0.13.0
func WithPathContext(ctx context.Context, fic *PathContext) context.Context
func WithResponseContext ¶ added in v0.11.0
func WithResponseContext(ctx context.Context, presenterFunc ErrorPresenterFunc, recoverFunc RecoverFunc) context.Context
func WithRootFieldContext ¶ added in v0.15.0
func WithRootFieldContext(ctx context.Context, rc *RootFieldContext) context.Context
Types ¶
type Cache ¶ added in v0.11.0
type Cache[T any] interface { // Get looks up a key's value from the cache. Get(ctx context.Context, key string) (value T, ok bool) // Add adds a value to the cache. Add(ctx context.Context, key string, value T) }
Cache is a shared store for APQ and query AST caching
type CollectedField ¶
type CollectedField struct { *ast.Field Selections ast.SelectionSet Deferrable *Deferrable }
func CollectFields ¶
func CollectFields(reqCtx *OperationContext, selSet ast.SelectionSet, satisfies []string) []CollectedField
CollectFields returns the set of fields from an ast.SelectionSet where all collected fields satisfy at least one of the GraphQL types passed through satisfies. Providing an empty or nil slice for satisfies will return collect all fields regardless of fragment type conditions.
func CollectFieldsCtx ¶
func CollectFieldsCtx(ctx context.Context, satisfies []string) []CollectedField
This is just a convenient wrapper method for CollectFields
type ContextMarshaler ¶ added in v0.15.0
func MarshalFloatContext ¶ added in v0.15.0
func MarshalFloatContext(f float64) ContextMarshaler
type ContextUnmarshaler ¶ added in v0.15.0
type ContextWriterFunc ¶ added in v0.15.0
func (ContextWriterFunc) MarshalGQLContext ¶ added in v0.15.0
type Deferrable ¶ added in v0.17.32
type Deferrable struct {
Label string
}
type DeferredGroup ¶ added in v0.17.32
type DeferredResult ¶ added in v0.17.32
type ErrorPresenterFunc ¶
type ExecutableSchema ¶
type ExecutableSchemaMock ¶ added in v0.11.0
type ExecutableSchemaMock struct { // ComplexityFunc mocks the Complexity method. ComplexityFunc func(typeName string, fieldName string, childComplexity int, args map[string]any) (int, bool) // ExecFunc mocks the Exec method. ExecFunc func(ctx context.Context) ResponseHandler // SchemaFunc mocks the Schema method. SchemaFunc func() *ast.Schema // contains filtered or unexported fields }
ExecutableSchemaMock is a mock implementation of ExecutableSchema.
func TestSomethingThatUsesExecutableSchema(t *testing.T) { // make and configure a mocked ExecutableSchema mockedExecutableSchema := &ExecutableSchemaMock{ ComplexityFunc: func(typeName string, fieldName string, childComplexity int, args map[string]any) (int, bool) { panic("mock out the Complexity method") }, ExecFunc: func(ctx context.Context) ResponseHandler { panic("mock out the Exec method") }, SchemaFunc: func() *ast.Schema { panic("mock out the Schema method") }, } // use mockedExecutableSchema in code that requires ExecutableSchema // and then make assertions. }
func (*ExecutableSchemaMock) Complexity ¶ added in v0.11.0
func (mock *ExecutableSchemaMock) Complexity(typeName string, fieldName string, childComplexity int, args map[string]any) (int, bool)
Complexity calls ComplexityFunc.
func (*ExecutableSchemaMock) ComplexityCalls ¶ added in v0.11.0
func (mock *ExecutableSchemaMock) ComplexityCalls() []struct { TypeName string FieldName string ChildComplexity int Args map[string]any }
ComplexityCalls gets all the calls that were made to Complexity. Check the length with:
len(mockedExecutableSchema.ComplexityCalls())
func (*ExecutableSchemaMock) Exec ¶ added in v0.11.0
func (mock *ExecutableSchemaMock) Exec(ctx context.Context) ResponseHandler
Exec calls ExecFunc.
func (*ExecutableSchemaMock) ExecCalls ¶ added in v0.11.0
func (mock *ExecutableSchemaMock) ExecCalls() []struct { Ctx context.Context }
ExecCalls gets all the calls that were made to Exec. Check the length with:
len(mockedExecutableSchema.ExecCalls())
func (*ExecutableSchemaMock) Schema ¶ added in v0.11.0
func (mock *ExecutableSchemaMock) Schema() *ast.Schema
Schema calls SchemaFunc.
func (*ExecutableSchemaMock) SchemaCalls ¶ added in v0.11.0
func (mock *ExecutableSchemaMock) SchemaCalls() []struct { }
SchemaCalls gets all the calls that were made to Schema. Check the length with:
len(mockedExecutableSchema.SchemaCalls())
type FieldContext ¶ added in v0.11.0
type FieldContext struct { Parent *FieldContext // The name of the type this field belongs to Object string // These are the args after processing, they can be mutated in middleware to change what the resolver will get. Args map[string]any // The raw field Field CollectedField // The index of array in path. Index *int // The result object of resolver Result any // IsMethod indicates if the resolver is a method IsMethod bool // IsResolver indicates if the field has a user-specified resolver IsResolver bool // Child allows getting a child FieldContext by its field collection description. // Note that, the returned child FieldContext represents the context as it was // before the execution of the field resolver. For example: // // srv.AroundFields(func(ctx context.Context, next graphql.Resolver) (interface{}, error) { // fc := graphql.GetFieldContext(ctx) // opCtx := graphql.GetOperationContext(ctx) // collected := graphql.CollectFields(opCtx, fc.Field.Selections, []string{"User"}) // // child, err := fc.Child(ctx, collected[0]) // if err != nil { // return nil, err // } // fmt.Printf("child context %q with args: %v\n", child.Field.Name, child.Args) // // return next(ctx) // }) // Child func(context.Context, CollectedField) (*FieldContext, error) }
func GetFieldContext ¶ added in v0.11.0
func GetFieldContext(ctx context.Context) *FieldContext
func (*FieldContext) Path ¶ added in v0.11.0
func (r *FieldContext) Path() ast.Path
type FieldInterceptor ¶ added in v0.11.0
type FieldInterceptor interface {
InterceptField(ctx context.Context, next Resolver) (res any, err error)
}
FieldInterceptor called around each field
type FieldMiddleware ¶
type FieldSet ¶ added in v0.8.0
type FieldSet struct { Values []Marshaler Invalids uint32 // contains filtered or unexported fields }
func NewFieldSet ¶ added in v0.8.0
func NewFieldSet(fields []CollectedField) *FieldSet
func (*FieldSet) AddField ¶ added in v0.17.32
func (m *FieldSet) AddField(field CollectedField)
func (*FieldSet) Concurrently ¶ added in v0.8.0
func (*FieldSet) MarshalGQL ¶ added in v0.8.0
type FieldStats ¶ added in v0.11.0
type GraphExecutor ¶ added in v0.11.0
type HandlerExtension ¶ added in v0.11.0
type HandlerExtension interface { // ExtensionName should be a CamelCase string version of the extension which may be shown in stats and logging. ExtensionName() string // Validate is called when adding an extension to the server, it allows validation against the servers schema. Validate(schema ExecutableSchema) error }
HandlerExtension adds functionality to the http handler. See the list of possible hook points below Its important to understand the lifecycle of a graphql request and the terminology we use in gqlgen before working with these
+--- REQUEST POST /graphql --------------------------------------------+ | +- OPERATION query OpName { viewer { name } } -----------------------+ | | | RESPONSE { "data": { "viewer": { "name": "bob" } } } | | | +- OPERATION subscription OpName2 { chat { message } } --------------+ | | | RESPONSE { "data": { "chat": { "message": "hello" } } } | | | | RESPONSE { "data": { "chat": { "message": "byee" } } } | | | +--------------------------------------------------------------------+ | +------------------------------------------------------------------------+
type MapCache ¶ added in v0.11.0
MapCache is the simplest implementation of a cache, because it can not evict it should only be used in tests
type Marshaler ¶
func MarshalAny ¶ added in v0.9.0
func MarshalBoolean ¶
func MarshalDuration ¶ added in v0.17.39
MarshalDuration returns the duration on ISO8601 format
func MarshalFloat ¶
func MarshalInt ¶
func MarshalInt32 ¶ added in v0.8.0
func MarshalInt64 ¶ added in v0.8.0
func MarshalIntID ¶ added in v0.8.0
func MarshalMap ¶
func MarshalString ¶
func MarshalTime ¶
func MarshalUUID ¶ added in v0.17.37
func MarshalUint ¶ added in v0.14.0
func MarshalUint32 ¶ added in v0.14.0
func MarshalUint64 ¶ added in v0.14.0
func MarshalUintID ¶ added in v0.17.46
func MarshalUpload ¶ added in v0.9.0
func WrapContextMarshaler ¶ added in v0.15.0
func WrapContextMarshaler(ctx context.Context, m ContextMarshaler) Marshaler
type Omittable ¶ added in v0.17.31
type Omittable[T any] struct { // contains filtered or unexported fields }
Omittable is a wrapper around a value that also stores whether it is set or not.
func OmittableOf ¶ added in v0.17.31
func (Omittable[T]) MarshalJSON ¶ added in v0.17.41
func (*Omittable[T]) UnmarshalJSON ¶ added in v0.17.41
type OperationContext ¶ added in v0.11.0
type OperationContext struct { RawQuery string Variables map[string]any OperationName string Doc *ast.QueryDocument Headers http.Header Operation *ast.OperationDefinition DisableIntrospection bool RecoverFunc RecoverFunc ResolverMiddleware FieldMiddleware RootResolverMiddleware RootFieldMiddleware Stats Stats }
func GetOperationContext ¶ added in v0.11.0
func GetOperationContext(ctx context.Context) *OperationContext
func (*OperationContext) Error ¶ added in v0.11.0
func (c *OperationContext) Error(ctx context.Context, err error)
Error add error or multiple errors (if underlaying type is gqlerror.List) into the stack. Then it will be sends to the client, passing it through the formatter.
func (*OperationContext) Errorf ¶ added in v0.11.0
func (c *OperationContext) Errorf(ctx context.Context, format string, args ...any)
Errorf sends an error string to the client, passing it through the formatter. Deprecated: use graphql.AddErrorf(ctx, err) instead
type OperationContextMutator ¶ added in v0.11.0
type OperationContextMutator interface {
MutateOperationContext(ctx context.Context, opCtx *OperationContext) *gqlerror.Error
}
OperationContextMutator is called after creating the request context, but before executing the root resolver.
type OperationHandler ¶ added in v0.11.0
type OperationHandler func(ctx context.Context) ResponseHandler
type OperationInterceptor ¶ added in v0.11.0
type OperationInterceptor interface {
InterceptOperation(ctx context.Context, next OperationHandler) ResponseHandler
}
OperationInterceptor is called for each incoming query, for basic requests the writer will be invoked once, for subscriptions it will be invoked multiple times.
type OperationMiddleware ¶ added in v0.11.0
type OperationMiddleware func(ctx context.Context, next OperationHandler) ResponseHandler
type OperationParameterMutator ¶ added in v0.11.0
type OperationParameterMutator interface {
MutateOperationParameters(ctx context.Context, request *RawParams) *gqlerror.Error
}
OperationParameterMutator is called before creating a request context. allows manipulating the raw query on the way in.
type PathContext ¶ added in v0.13.0
type PathContext struct { ParentField *FieldContext Parent *PathContext Field *string Index *int }
func GetPathContext ¶ added in v0.13.0
func GetPathContext(ctx context.Context) *PathContext
func NewPathWithField ¶ added in v0.13.0
func NewPathWithField(field string) *PathContext
func NewPathWithIndex ¶ added in v0.13.0
func NewPathWithIndex(index int) *PathContext
func (*PathContext) Path ¶ added in v0.13.0
func (fic *PathContext) Path() ast.Path
type RawParams ¶ added in v0.11.0
type RequestContext
deprecated
type RequestContext = OperationContext
Deprecated: Please update all references to OperationContext instead
func GetRequestContext
deprecated
func GetRequestContext(ctx context.Context) *RequestContext
Deprecated: Please update all references to GetOperationContext instead
type ResolverContext
deprecated
type ResolverContext = FieldContext
Deprecated: Use FieldContext instead
func GetResolverContext
deprecated
func GetResolverContext(ctx context.Context) *ResolverContext
Deprecated: Use GetFieldContext instead
type Response ¶
type Response struct { Errors gqlerror.List `json:"errors,omitempty"` Data json.RawMessage `json:"data"` Label string `json:"label,omitempty"` Path ast.Path `json:"path,omitempty"` HasNext *bool `json:"hasNext,omitempty"` Extensions map[string]any `json:"extensions,omitempty"` }
Errors are intentionally serialized first based on the advice in https://github.com/facebook/graphql/commit/7b40390d48680b15cb93e02d46ac5eb249689876#diff-757cea6edf0288677a9eea4cfc801d87R107 and https://github.com/facebook/graphql/pull/384
type ResponseHandler ¶ added in v0.11.0
func OneShot ¶
func OneShot(resp *Response) ResponseHandler
type ResponseInterceptor ¶ added in v0.11.0
type ResponseInterceptor interface {
InterceptResponse(ctx context.Context, next ResponseHandler) *Response
}
ResponseInterceptor is called around each graphql operation response. This can be called many times for a single operation the case of subscriptions.
type ResponseMiddleware ¶ added in v0.11.0
type ResponseMiddleware func(ctx context.Context, next ResponseHandler) *Response
type RootFieldContext ¶ added in v0.15.0
type RootFieldContext struct { // The name of the type this field belongs to Object string // The raw field Field CollectedField }
func GetRootFieldContext ¶ added in v0.15.0
func GetRootFieldContext(ctx context.Context) *RootFieldContext
type RootFieldInterceptor ¶ added in v0.15.0
type RootFieldInterceptor interface {
InterceptRootField(ctx context.Context, next RootResolver) Marshaler
}
type RootFieldMiddleware ¶ added in v0.15.0
type RootFieldMiddleware func(ctx context.Context, next RootResolver) Marshaler
type RootResolver ¶ added in v0.15.0
type Stats ¶ added in v0.11.0
type Stats struct { OperationStart time.Time Read TraceTiming Parsing TraceTiming Validation TraceTiming // contains filtered or unexported fields }
func (*Stats) GetExtension ¶ added in v0.11.0
func (*Stats) SetExtension ¶ added in v0.11.0
type Subscription ¶ added in v0.8.0
type Subscription struct{}
type Transport ¶ added in v0.11.0
type Transport interface { Supports(r *http.Request) bool Do(w http.ResponseWriter, r *http.Request, exec GraphExecutor) }
Transport provides support for different wire level encodings of graphql requests, eg Form, Get, Post, Websocket
type Unmarshaler ¶
type Upload ¶ added in v0.9.0
type Upload struct { File io.ReadSeeker Filename string Size int64 ContentType string }
func UnmarshalUpload ¶ added in v0.9.0
type WriterFunc ¶
func (WriterFunc) MarshalGQL ¶
func (f WriterFunc) MarshalGQL(w io.Writer)
Source Files ¶
- any.go
- bool.go
- cache.go
- coercion.go
- context_field.go
- context_operation.go
- context_path.go
- context_response.go
- context_root_field.go
- deferred.go
- duration.go
- error.go
- executable_schema.go
- executable_schema_mock.go
- fieldset.go
- float.go
- handler.go
- id.go
- input.go
- int.go
- jsonw.go
- map.go
- omittable.go
- oneshot.go
- recovery.go
- response.go
- root.go
- stats.go
- string.go
- time.go
- uint.go
- upload.go
- uuid.go
- version.go
Directories ¶
Path | Synopsis |
---|---|
introspection implements the spec defined in https://github.com/facebook/graphql/blob/master/spec/Section%204%20--%20Introspection.md#schema-introspection
|
introspection implements the spec defined in https://github.com/facebook/graphql/blob/master/spec/Section%204%20--%20Introspection.md#schema-introspection |