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.