I am using gqlgen
, sqlx
and pgx
. Trying to use custom scalar to store as jonb type in postgres database.
// graph/model/item.go
type Attributes types.JSONText
// Marshal here
...
func (a *Attributes) UnmarshalGQL(v interface{}) error {
switch v := v.(type) {
case []byte:
log.Println(" >> unmarshal.byte:", v)
json.Unmarshal(v, &a)
return nil
case string:
log.Println(" >> unmarshal.string:", v) // >> unmarshal.string: {"target": "localhost"}
json.Unmarshal([]byte(v), a) // This gives `null` in postgres
log.Println(" >> unmarshal.aT:", reflect.TypeOf(a)) // >> unmarshal.aT: *model.Attributes
log.Println(" >> unmarshal.aV:", reflect.ValueOf(a)) // >> unmarshal.aV: &[]
return nil
default:
return errors.New(fmt.Sprintf("Unsupported type: %T", v))
}
}
The desired result of a *Attributes
should be {"target": "localhost"}
, to store as jsonb in postgres:
| id | quantity | attributes |
|----|----------|-------------------------|
| 1 | 5 | {"target": "localhost"} |
What I am doing wrong?
Edit: Add sample mutation.
This is the sample mutation:
mutation itemCreate {
itemCreate(input: {
quantity: 5,
attributes: "{\"target\": \"localhost\"}"
})
}
Edit: Add sqlx query.
The query to insert:
func (d *ItemDb) ItemCreate(i *model.ItemInput) (*model.Item, error) {
log.Println(" >> i.Attributes:", i.Attributes) // >> i.Attributes: &[123 34 116 97 114 103 101 116 34 58 32 34 108 111 99 97 108 104 111 115 116 34 125]
item := &model.Item{}
if err := d.Get(item, `INSERT INTO items
(quantity, attributes)
VALUES ($1, $2)
RETURNING *`, i.Quantity, i.Attributes); err != nil {
return nil, err
}
return item, nil
}
If
v
contains literal json in either[]byte
orstring
then there's no need forjson.Unmarshal
, all that should be needed is a conversion.