使用gqlgen + Gorm时,对于Uint类型会引发错误
请用中文回答以下问题:
这次的话题是什么?
当使用gqlgen + Gorm时,返回Uint类型的列值时会出现类型错误,无法成功获取数据,因此在这里记录解决方法。
定義模型的结构体
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系列的类型,所以您需要自己准备标量。
在我的研究中,我发现已经有了一个很棒的解决方案,所以我借用了它。
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 请将以下内容用中文进行释义:
定义了一个附加的标量
...略
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"
GraphQL的模式结构
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
参考来源的网站 de
以下是中文的原生概述,请选择其中一种选项:
1. 源代码链接:https://gist.github.com/JonLundy/ad750704b83aebec69749f98ba48dcdc
2. gqlgen链接:https://github.com/99designs/gqlgen
3. GORM官方文档链接(日文):https://gorm.io/ja_JP/docs/index.html