github.com/fortexxx/gqlgen@v0.10.3-0.20191216030626-ca5ea8b21ead/docs/content/reference/scalars.md (about) 1 --- 2 linkTitle: Scalars 3 title: Mapping GraphQL scalar types to Go types 4 description: Mapping GraphQL scalar types to Go types 5 menu: { main: { parent: "reference" } } 6 --- 7 8 ## Built-in helpers 9 10 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. 11 12 ### Time 13 14 ```graphql 15 scalar Time 16 ``` 17 18 Maps a `Time` GraphQL scalar to a Go `time.Time` struct. 19 20 ### Map 21 22 ```graphql 23 scalar Map 24 ``` 25 26 Maps an arbitrary GraphQL value to a `map[string]interface{}` Go type. 27 28 ### Upload 29 30 ```graphql 31 scalar Upload 32 ``` 33 34 Maps a `Upload` GraphQL scalar to a `graphql.Upload` struct, defined as follows: 35 36 ```go 37 type Upload struct { 38 File io.Reader 39 Filename string 40 Size int64 41 } 42 ``` 43 44 ### Any 45 46 ```graphql 47 scalar Any 48 ``` 49 50 Maps an arbitrary GraphQL value to a `interface{}` Go type. 51 52 ## Custom scalars with user defined types 53 54 For user defined types you can implement the graphql.Marshaler and graphql.Unmarshaler interfaces and they will be called. 55 56 ```go 57 package mypkg 58 59 import ( 60 "fmt" 61 "io" 62 "strings" 63 ) 64 65 type YesNo bool 66 67 // UnmarshalGQL implements the graphql.Unmarshaler interface 68 func (y *YesNo) UnmarshalGQL(v interface{}) error { 69 yes, ok := v.(string) 70 if !ok { 71 return fmt.Errorf("points must be strings") 72 } 73 74 if yes == "yes" { 75 *y = true 76 } else { 77 *y = false 78 } 79 return nil 80 } 81 82 // MarshalGQL implements the graphql.Marshaler interface 83 func (y YesNo) MarshalGQL(w io.Writer) { 84 if y { 85 w.Write([]byte(`"yes"`)) 86 } else { 87 w.Write([]byte(`"no"`)) 88 } 89 } 90 ``` 91 92 and then in .gqlgen.yml point to the name without the Marshal|Unmarshal in front: 93 94 ```yaml 95 models: 96 YesNo: 97 model: github.com/me/mypkg.YesNo 98 ``` 99 100 ## Custom scalars with third party types 101 102 Sometimes you cant add methods to a type because its in another repo, part of the standard 103 library (eg string or time.Time). To do this we can build an external marshaler: 104 105 ```go 106 package mypkg 107 108 import ( 109 "fmt" 110 "io" 111 "strings" 112 113 "github.com/99designs/gqlgen/graphql" 114 ) 115 116 117 func MarshalMyCustomBooleanScalar(b bool) graphql.Marshaler { 118 return graphql.WriterFunc(func(w io.Writer) { 119 if b { 120 w.Write([]byte("true")) 121 } else { 122 w.Write([]byte("false")) 123 } 124 }) 125 } 126 127 func UnmarshalMyCustomBooleanScalar(v interface{}) (bool, error) { 128 switch v := v.(type) { 129 case string: 130 return "true" == strings.ToLower(v), nil 131 case int: 132 return v != 0, nil 133 case bool: 134 return v, nil 135 default: 136 return false, fmt.Errorf("%T is not a bool", v) 137 } 138 } 139 ``` 140 141 Then in .gqlgen.yml point to the name without the Marshal|Unmarshal in front: 142 143 ```yaml 144 models: 145 MyCustomBooleanScalar: 146 model: github.com/me/mypkg.MyCustomBooleanScalar 147 ``` 148 149 See the [example/scalars](https://github.com/99designs/gqlgen/tree/master/example/scalars) package for more examples.