gqlgen + Gorm でUint型の場合エラーになる

# 今回のお題
gqlgen + Gorm を使った時にUint型のカラム値を返却する時に、型エラーが発生しうまくデータ取得できなかったので、その解消方法を記載します。

## 定義したモデルの構造体


```db_model.go
package db_model

import (
	_ "github.com/jinzhu/gorm/dialects/mysql"
	"time"
)

type User struct {
	ID        uint32    `gorm:"primary_key;AUTO_INCREMENT;"`
	Name      string    `gorm:"size:255"`
	Password  string    `gorm:"size:255"`
	Email     string    `gorm:"size:255"`
	CreatedAt time.Time `gorm:"column:created_at;type:datetime;"`
	UpdatedAt time.Time `gorm:"column:updated_at;type:datetime;"`
	Items     []Item    `gorm:"foreignkey:ID"`
}

type Item struct {
	ID        uint32 `gorm:"primary_key;AUTO_INCREMENT;"`
	Name      string
	UserID    uint32
	CreatedAt time.Time `gorm:"column:created_at;type:datetime;"`
	UpdatedAt time.Time `gorm:"column:updated_at;type:datetime;"`
}
```
これを元にGormのAutoMigrateを実行してテーブル作成します。

## 自前スカラーの定義
gqlgenはUint系の型をサポートしていないので、自前でスカラーを準備する必要があります。
調べていたら、すでに対応されている素晴らしい方でいたのでそれを拝借させて頂きました。

```graph/model/uint.go
package model

import (
	"encoding/json"
	"fmt"
	"io"
	"strconv"

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

func MarshalUint(t uint) graphql.Marshaler {
	return MarshalUint64(uint64(t))
}

func UnmarshalUint(v interface{}) (uint, error) {
	i, err := UnmarshalUint64(v)
	return uint(i), err
}

func MarshalUint64(t uint64) graphql.Marshaler {
	return graphql.WriterFunc(func(w io.Writer) {
		_, err := io.WriteString(w, strconv.FormatUint(t, 10))
		if err != nil {
			return
		}
	})
}

func UnmarshalUint64(v interface{}) (uint64, error) {
	switch t := v.(type) {
	case string:
		return strconv.ParseUint(t, 10, 64)
	case int:
		return uint64(t), nil
	case int64:
		return uint64(t), nil
	case json.Number:
		i, err := t.Int64()
		return uint64(i), err
	case float64:
		return uint64(t), nil
	}

	return 0, fmt.Errorf("unable to unmarshal uint64: %#v %T", v, v)
}

func MarshalUint32(t uint32) graphql.Marshaler {
	return graphql.WriterFunc(func(w io.Writer) {
		_, err := io.WriteString(w, strconv.FormatUint(uint64(t), 10))
		if err != nil {
			return
		}
	})
}

func UnmarshalUint32(v interface{}) (uint32, error) {
	switch t := v.(type) {
	case string:
		u, err := strconv.ParseUint(t, 10, 32)
		return uint32(u), err
	case int:
		return uint32(t), nil
	case int64:
		return uint32(t), nil
	case json.Number:
		i, err := t.Int64()
		return uint32(i), err
	case float64:
		return uint32(t), nil
	}

	return 0, fmt.Errorf("unable to unmarshal uint32: %#v %T", v, v)
}

```

## gqlgen.yml
追加したスカラーを定義する

```gqlgen.yml
...略
models:
  ID:
    model:
      - github.com/99designs/gqlgen/graphql.ID
      - github.com/99designs/gqlgen/graphql.Int
      - github.com/99designs/gqlgen/graphql.Int64
      - github.com/99designs/gqlgen/graphql.Int32
  Int:
    model:
      - github.com/99designs/gqlgen/graphql.Int
      - github.com/99designs/gqlgen/graphql.Int64
      - github.com/99designs/gqlgen/graphql.Int32
  User:
    model: "github.com/bb3104/gqlgen_gorm_sample/db_model.User"
  Item:
    model: "github.com/bb3104/gqlgen_gorm_sample/db_model.Item"
-------- ここから追加 ---------
  Uint:
    model: "github.com/bb3104/gqlgen_gorm_sample/graph/model.Uint"
  Uint32:
    model: "github.com/bb3104/gqlgen_gorm_sample/graph/model.Uint32"
  Uint64:
    model: "github.com/bb3104/gqlgen_gorm_sample/graph/model.Uint64"
```

## grahpqlのスキーマ構造
```graph/schema.graphqls
type User {
  id: Uint32!　<- 最初はここにID!を定義してた為、Graphqlクエリのレスポンス結果がエラーになった。
  name: String!
  password: String!
  email: String!
  items: [Item!]
  createdAt: Time!
  updatedAt: Time!
}

type Item {
  id: Uint32!
  name: String!
  createdAt: Time!
  updatedAt: Time!
}

type Query {
  users: [User!]!
}

scalar Time
scalar Uint32 <- 追加

```

これでGormで作成したIDカラムの型とスキーマ構造で定義したIDの型がイコールになって、無事解決！！

上記内容はgithubにソースコードがありますので、よかったらぜひご覧になってみてください。
https://github.com/bb3104/gqlgen_gorm_sample

## 参考にしたサイト
https://gist.github.com/JonLundy/ad750704b83aebec69749f98ba48dcdc
https://github.com/99designs/gqlgen
https://gorm.io/ja_JP/docs/index.html