gographqlgraphql-go

Some of my go-graphql queries' fields are returning null while other fields come back fine and other similar queries work all together


I have been experimenting with go-grapqhql and I have been able to successfully create some schemas such as this:

type Artist struct {
    ID   string `json:"id,omitempty"`
    Name string `json:"name"`
    Type string `json:"type"`
    Instrument []Instrument `json:"instrument"`
}

type Instrument struct{
    Name string `json:"name"`
}

var artists = []Artist{
    {
        ID:   "1",
        Name: "Taylor Swift",
        Type: "artist",
        Instrument: []Instrument{
            {Name:"violin"},
        },
    },
}

var instrumentType = graphql.NewObject(graphql.ObjectConfig{
    Name: "Instrument",
    Fields: graphql.Fields{
        "name": &graphql.Field{
            Type: graphql.String,
        },
    },
})

var artistType = graphql.NewObject(graphql.ObjectConfig{
    Name: "Artist",
    Fields: graphql.Fields{
        "id": &graphql.Field{
            Type: graphql.String,
        },
        "name": &graphql.Field{
            Type: graphql.String,
        },
        "type": &graphql.Field{
            Type: graphql.String,
        },
        "instrument": &graphql.Field{
            Type: graphql.NewList(instrumentType),
        },
    },
})

However, when I try and do the same thing with a similar struct...

type Blk struct {
    Header Header `json:"header,omitempty"`
    Payload []Payload `json:"payload,omitempty"`
}

type Header struct {
    Parent string `json:"parent,omitempty"`
    Number int `json:"number,omitempty"`
    Nonce int `json:"nonce,omitempty"`
    Time int `json:"time,omitempty"`
    Miner string `json:"miner,omitempty"`
}

type Payloads []Payloads

type Payload struct {
    From string `json:"from,omitempty"`
    To string `json:"to,omitempty"`
    Value int `json:"value,omitempty"`
    Nonce int `json:"nonce,omitempty"`
    Data string `json:"data,omitempty"`
    Time int `json:"time,omitempty"`
    Signature string `json:"signature,omitempty"`
}

var blk = []Blk{
    {Header: Header{
        Parent: "0000000000000000000000000000000000000000000000000000000000000000",
        Number: 0,
        Nonce:  1548399560,
        Time:   1609374088,
        Miner:  "0x699ecb24665b9734c420db0f75ed9677a8615eb1",
    },
        Payload: []Payload{
            {
                From:      "0x699ecb24665b9734c420db0f75ed9677a8615eb1",
                To:        "0x4adb5430e58171aa233a12d95b89d4ff2f211bcb",
                Value:     100000,
                Nonce:     1,
                Data:      "",
                Time:      1609374076,
                Signature: "tzRWXErhQwR9wHje9gT6tNTftZ07KN9G+MHgh0Ock5YgDMXkCL611D4xruq9pULQfS+j1HPkbo9VyCWxSxDfMwA=",
            },
        },
    },
}

var transactionType = graphql.NewObject(
    graphql.ObjectConfig{
        Name: "payload",
        Fields: graphql.Fields{
            "from": &graphql.Field{
                Type: graphql.String,
            },
            "to": &graphql.Field{
                Type: graphql.String,
            },
            "value": &graphql.Field{
                Type: graphql.Int,
            },
            "nonce": &graphql.Field{
                Type: graphql.Int,
            },
            "data": &graphql.Field{
                Type: graphql.String,
            },
            "time": &graphql.Field{
                Type: graphql.Int,
            },
            "signature": &graphql.Field{
                Type: graphql.String,
            },
        },
    })

var blocksType = graphql.NewObject(
    graphql.ObjectConfig{
        Name: "header",
        Fields: graphql.Fields{
            "parent": &graphql.Field{
                Type: graphql.String,
            },
            "number": &graphql.Field{
                Type: graphql.Int,
            },
            "nonce": &graphql.Field{
                Type: graphql.Int,
            },
            "time": &graphql.Field{
                Type: graphql.Int,
            },
            "miner": &graphql.Field{
                Type: graphql.String,
            },
            "payload": &graphql.Field{
                Type: graphql.NewList(transactionType),
            },
        },
    },
)

My queries only return null ie. the query

query{
artists{id,instrument{name}}
}

returns

{
    "data": {
        "artists": [
            {
                "id": "1",
                "instrument": [
                    {
                        "name": "violin"
                    }
                ]
            }
        ]
    }
}

Which is great, but the query

query{
blocks{parent,number,nonce,time,miner, payload{from, to,value, nonce, data, time, signature}}
}

returns

{
    "data": {
        "blocks": [
            {
                "miner": null,
                "nonce": null,
                "number": null,
                "parent": null,
                "payload": [
                    {
                        "data": "",
                        "from": "0x699ecb24665b9734c420db0f75ed9677a8615eb1",
                        "nonce": 1,
                        "signature": "tzRWXErhQwR9wHje9gT6tNTftZ07KN9G+MHgh0Ock5YgDMXkCL611D4xruq9pULQfS+j1HPkbo9VyCWxSxDfMwA=",
                        "time": 1609374076,
                        "to": "0x4adb5430e58171aa233a12d95b89d4ff2f211bcb",
                        "value": 100000
                    }
                ],
                "time": null
            }
        ]
    }
}

which is not great. I have been trying different things such as making all the fields strings but nothing has worked.


Solution

  • So, I changed the graphql schema to be :

    var blockType = graphql.NewObject(
        graphql.ObjectConfig{
            Name: "block",
            Fields: graphql.Fields{
                "header" :&graphql.Field{
                    Type: headerType,
                },
                "payload": &graphql.Field{
                    Type: graphql.NewList(payloadType),
                },
            },
        })
    
    var payloadType = graphql.NewObject(
        graphql.ObjectConfig{
            Name: "payload",
            Fields: graphql.Fields{
                "from": &graphql.Field{
                    Type: graphql.String,
                },
                "to": &graphql.Field{
                    Type: graphql.String,
                },
                "value": &graphql.Field{
                    Type: graphql.Int,
                },
                "nonce": &graphql.Field{
                    Type: graphql.Int,
                },
                "data": &graphql.Field{
                    Type: graphql.String,
                },
                "time": &graphql.Field{
                    Type: graphql.Int,
                },
                "signature": &graphql.Field{
                    Type: graphql.String,
                },
            },
        })
    
    var headerType = graphql.NewObject(
        graphql.ObjectConfig{
            Name: "header",
            Fields: graphql.Fields{
                "parent": &graphql.Field{
                    Type: graphql.String,
                },
                "number": &graphql.Field{
                    Type: graphql.Int,
                },
                "nonce": &graphql.Field{
                    Type: graphql.Int,
                },
                "time": &graphql.Field{
                    Type: graphql.Int,
                },
                "miner": &graphql.Field{
                    Type: graphql.String,
                },
            },
        },
    )
    

    Now, it all works as expected. It seems this line was the culprit:

         "payload": &graphql.Field{
                    Type: graphql.NewList(transactionType),
                },
    

    For some reason or another, if you try and do this type of nesting go-graphql (or graphql can't figure out what to do). FWI: now my queries look like this:

    query{
        blocks{header{parent,number,nonce,time,miner},payload{from,to,value,nonce,data,time,signature}}
    }
    

    and they yield the required result.