v0.11.3
v0.11.3 v0.17.10 v0.17.9 v0.17.8 v0.17.7 v0.17.6 v0.17.5 v0.17.4 v0.17.3 v0.17.2 v0.17.1 v0.17.0 v0.16.0 v0.15.1 v0.15.0 v0.14.0 v0.13.0 v0.12.2 v0.12.1 v0.12.0 master

Scalars

Mapping GraphQL scalar types to Go types
[edit]
You are looking at the docs for an older version (v0.11.3). The latest version is v0.17.10.

Built-in helpers

gqlgen ships with some built-in helpers for common custom scalar use-cases, Time, Any, Upload and Map. Adding any of these to a schema will automatically add the marshalling behaviour to Go types.

Time

scalar Time

Maps a Time GraphQL scalar to a Go time.Time struct.

Map

scalar Map

Maps an arbitrary GraphQL value to a map[string]interface{} Go type.

Upload

scalar Upload

Maps a Upload GraphQL scalar to a graphql.Upload struct, defined as follows:

type Upload struct {
	File        io.Reader
	Filename    string
	Size        int64
	ContentType string
}

Any

scalar Any

Maps an arbitrary GraphQL value to a interface{} Go type.

Custom scalars with user defined types

For user defined types you can implement the graphql.Marshaler and graphql.Unmarshaler interfaces and they will be called.

package mypkg

import (
	"fmt"
	"io"
	"strings"
)

type YesNo bool

// UnmarshalGQL implements the graphql.Unmarshaler interface
func (y *YesNo) UnmarshalGQL(v interface{}) error {
	yes, ok := v.(string)
	if !ok {
		return fmt.Errorf("points must be strings")
	}

	if yes == "yes" {
		*y = true
	} else {
		*y = false
	}
	return nil
}

// MarshalGQL implements the graphql.Marshaler interface
func (y YesNo) MarshalGQL(w io.Writer) {
	if y {
		w.Write([]byte(`"yes"`))
	} else {
		w.Write([]byte(`"no"`))
	}
}

and then in .gqlgen.yml point to the name without the Marshal|Unmarshal in front:

models:
  YesNo:
    model: github.com/me/mypkg.YesNo

Custom scalars with third party types

Sometimes you cant add methods to a type because its in another repo, part of the standard library (eg string or time.Time). To do this we can build an external marshaler:

package mypkg

import (
	"fmt"
	"io"
	"strings"

	"github.com/99designs/gqlgen/graphql"
)


func MarshalMyCustomBooleanScalar(b bool) graphql.Marshaler {
	return graphql.WriterFunc(func(w io.Writer) {
		if b {
			w.Write([]byte("true"))
		} else {
			w.Write([]byte("false"))
		}
	})
}

func UnmarshalMyCustomBooleanScalar(v interface{}) (bool, error) {
	switch v := v.(type) {
	case string:
		return "true" == strings.ToLower(v), nil
	case int:
		return v != 0, nil
	case bool:
		return v, nil
	default:
		return false, fmt.Errorf("%T is not a bool", v)
	}
}

Then in .gqlgen.yml point to the name without the Marshal|Unmarshal in front:

models:
  MyCustomBooleanScalar:
    model: github.com/me/mypkg.MyCustomBooleanScalar

See the example/scalars package for more examples.