field

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Sep 27, 2022 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package field is for analysing Go struct fields for use as GraphQL query fields (resolvers)

Index

Constants

View Source
const (
	// AllowSubscript etc control which options are allowed TODO: use build tags instead?
	AllowSubscript  = true // "subscript" option generates a resolver to subscript into a list (array/slice/map)
	AllowFieldID    = true // "field_id" option generates an extra "id" field for queries on a list (array/slice/map)
	AllowComplexity = true // "complexity" option specifies how to estimate the complexity of a resalver
)
View Source
const TagKey = "egg"

TagKey is tag string "key" for our app - used to find options in the field metadata (tag string)

Variables

View Source
var UnmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem()

UnmarshalerType is the dynamic type of the Unmarshaler interface It's used to check if a type has an UnmarshalEGGQL method, which indicates it is a custom scalar type. The way it is obtained is a little tricky - you first get the type of a ptr to an Unmarshaler (which

here is nil but that does not matter as we are only concerned with types not values) then get
the type of what it points to (using reflect.Type.Elem()).

Functions

func SplitArgs

func SplitArgs(s string) ([]string, error)

SplitArgs splits a string on commas and returns the resulting slice of strings. It ignores commas within strings, round brackets, square brackets or braces, which allows for "nested" structures. For example "a,b(c,d),e" => []string{ "a", "b(c,d)", "e" } An error is returned if there is a problem with the input string such as unmatched brackets.

func SplitWithDesc

func SplitWithDesc(s string) ([]string, string, error)

SplitWithDesc is like SplitArgs but also allows a trailing "description" (anything after the first #). On success, it returns a list of strings, the description (if any) and a nil error. A non-nil error is returned if there is a problem with the input string such as unmatched brackets.

Types

type ID

type ID string

ID indicates that a field is to be used as a GraphQL ID type

type Info

type Info struct {
	Name        string       // field name for use in GraphQL queries - based on metadata (tag) or Go struct field name
	GQLTypeName string       // GraphQL type name - usually empty but required if can't be deduced (eg enums)
	ResultType  reflect.Type // Type (Go) used to generate the resolver (GraphQL) type = field type, func return type, or element type for array/slice

	// The following are for function resolvers only
	Args            []string // name(s) of args to resolver function obtained from metadata
	ArgTypes        []string // corresp. type names - usually deduced from function parameter type but needed for ID and enums
	ArgDefaults     []string // corresp. default value(s) (as strings) where an empty string means there is no default
	ArgDescriptions []string // corresp. description of the argument
	HasContext      bool     // 1st function parameter is a context.Context (not a query argument)
	HasError        bool     // has 2 return values the 2nd of which is a Go error

	Embedded bool // embedded struct (which we use as a template for a GraphQL "interface")
	Empty    bool // embedded struct has no fields (which we use for a GraphQL "union")
	Nullable bool // pointers (plus slice/map if "nullable" option was specified)
	IsChan   bool // field must be/return a channel for subscription fields (only)

	Directives []string // directives to apply to the field (eg "@deprecated")

	// Subscript holds the result of the "subscript" option (for a slice/array/map)
	Subscript string // name of resolver arg (default is "id")
	// FieldID holds the result of the "field_id" option (for a slice/array/map)
	FieldID string // name of id field (default is "id")
	// BaseIndex is the offset (from zero) for numeric IDs (slice/array only)
	// Eg if BaseIndex is 10 then ID 10 refers to element 0, ID 11 => element 1, etc
	// This is only used in conjunction with Subscript or FieldID options (on slices/arrays, but not maps)
	BaseIndex int
	// ElementType is the type of elements if the field is a map/slice/array - only used if FieldID or Subscript are not empty
	ElementType reflect.Type //  int for slice/array, type of the key for maps
	// Description is text used as a GraphQL description for the field - taken from the tag string after any # character (outside brackets)
	Description string // All text in the tag after the first hash (#) [unless the # is in brackets or in a string]
}

Info is returned from Get() with info extracted from a struct field to be used as a GraphQL query resolver. The info is obtained from the field's name, type and field's tag string (using TagKey). Note that the GraphQL type is usually deduced but sometimes needs to be supplied (saved in GQLTypeName for the resolver return type and ArgTypes is for resolver arguments) - but this is currently only necessary for GraphQL ID type for enum names (can't be deduced since Go does not have an enum type).

func Get

func Get(f *reflect.StructField) (fieldInfo *Info, err error)

Get checks if a field (of a Go struct) is exported and, if so, returns the GraphQL field info. incl. the

field name, derived from the Go field name (with 1st char lower-cased) or taken from the tag (metadata).
It also returns other stuff like whether the result is nullable and GraphQL parameters (and default
parameter values) if the resolver is a function.

Returns

  • ptr to field.Info, or nil if the field is not used (ie: not exported or metadata is just a dash (-)) A special case is a field name of underscore (_) which return field.Info but only with the Description field set
  • error for different reasons such as:
  • malformed metadata such as an unknown option (not one of args, nullable, subscript, field_id, base)
  • type of the field is invalid (eg resolver function with no return value)
  • inconsistency between the type and metadata (eg function parameters do not match the "args" option)

func GetInfoFromTag

func GetInfoFromTag(tag string) (*Info, error)

GetInfoFromTag extracts GraphQL field name and type info from the field's tag (if any) If the tag just contains a dash (-) then nil is returned (no error). If the tag string is empty (e.g. if no tag was supplied) then the returned Info is not nil but the Name field is empty.

type Marshaler

type Marshaler interface {
	MarshalEGGQL() (string, error)
}

Marshaler may be implemented by custom scalar types to encode the type in a string It should create a string compatible with Unmarshaller (above). If not given then the fmt.Stringer is used (ie String() method is called), and

if that's not implemented then fmt.Sprintf with %v is used

type Unmarshaler

type Unmarshaler interface {
	UnmarshalEGGQL(string) error
}

Unmarshaler must be implemented by custom scalar types to decode a string into the type It must be able to handle a string created with MarshalerEGGQL() (below) [or String() if there is no marshaler]

Jump to

Keyboard shortcuts

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