git.sr.ht/~sircmpwn/gqlgen@v0.0.0-20200522192042-c84d29a1c940/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  	ContentType string
    42  }
    43  ```
    44  
    45  ### Any
    46  
    47  ```graphql
    48  scalar Any
    49  ```
    50  
    51  Maps an arbitrary GraphQL value to a `interface{}` Go type.
    52  
    53  ## Custom scalars with user defined types
    54  
    55  For user defined types you can implement the graphql.Marshaler and graphql.Unmarshaler interfaces and they will be called.
    56  
    57  ```go
    58  package mypkg
    59  
    60  import (
    61  	"fmt"
    62  	"io"
    63  	"strings"
    64  )
    65  
    66  type YesNo bool
    67  
    68  // UnmarshalGQL implements the graphql.Unmarshaler interface
    69  func (y *YesNo) UnmarshalGQL(v interface{}) error {
    70  	yes, ok := v.(string)
    71  	if !ok {
    72  		return fmt.Errorf("points must be strings")
    73  	}
    74  
    75  	if yes == "yes" {
    76  		*y = true
    77  	} else {
    78  		*y = false
    79  	}
    80  	return nil
    81  }
    82  
    83  // MarshalGQL implements the graphql.Marshaler interface
    84  func (y YesNo) MarshalGQL(w io.Writer) {
    85  	if y {
    86  		w.Write([]byte(`"yes"`))
    87  	} else {
    88  		w.Write([]byte(`"no"`))
    89  	}
    90  }
    91  ```
    92  
    93  and then in .gqlgen.yml point to the name without the Marshal|Unmarshal in front:
    94  
    95  ```yaml
    96  models:
    97    YesNo:
    98      model: github.com/me/mypkg.YesNo
    99  ```
   100  
   101  ## Custom scalars with third party types
   102  
   103  Sometimes you cant add methods to a type because its in another repo, part of the standard
   104  library (eg string or time.Time). To do this we can build an external marshaler:
   105  
   106  ```go
   107  package mypkg
   108  
   109  import (
   110  	"fmt"
   111  	"io"
   112  	"strings"
   113  
   114  	"git.sr.ht/~sircmpwn/gqlgen/graphql"
   115  )
   116  
   117  
   118  func MarshalMyCustomBooleanScalar(b bool) graphql.Marshaler {
   119  	return graphql.WriterFunc(func(w io.Writer) {
   120  		if b {
   121  			w.Write([]byte("true"))
   122  		} else {
   123  			w.Write([]byte("false"))
   124  		}
   125  	})
   126  }
   127  
   128  func UnmarshalMyCustomBooleanScalar(v interface{}) (bool, error) {
   129  	switch v := v.(type) {
   130  	case string:
   131  		return "true" == strings.ToLower(v), nil
   132  	case int:
   133  		return v != 0, nil
   134  	case bool:
   135  		return v, nil
   136  	default:
   137  		return false, fmt.Errorf("%T is not a bool", v)
   138  	}
   139  }
   140  ```
   141  
   142  Then in .gqlgen.yml point to the name without the Marshal|Unmarshal in front:
   143  
   144  ```yaml
   145  models:
   146    MyCustomBooleanScalar:
   147      model: github.com/me/mypkg.MyCustomBooleanScalar
   148  ```
   149  
   150  See the [example/scalars](https://git.sr.ht/~sircmpwn/gqlgen/tree/master/example/scalars) package for more examples.