hasura / go-graphql-client

Package graphql provides a GraphQL client implementation.
MIT License
395 stars 91 forks source link

Debugging queries #108

Closed zdevaty closed 12 months ago

zdevaty commented 12 months ago

Hi, I want to subscribe to an API, but I get an error:

failed to read JSON message: failed to get reader: received close frame: status = StatusCode(4500) and reason = "Syntax Error: Expected Name, found \"!\"."

But I don't know where that exclamation mark comes from. How can I debug this? Is there a way to print the query out before subscribing?

zdevaty commented 12 months ago

For reference, this is the code that I use for the subscription:

type DataPointsSubscription struct {
    Subscription struct {
        DataPointsSubscription []struct {
            Value graphql.String `graphql:"value"`
        } `graphql:"DataPointsSubscription(datapointList: $datapointList)"`
    } `graphql:"subscription"`
}

func SubscribeDataPointValue(authToken string, datapoints []appdb.Datapoint) error {
    client := graphql.NewSubscriptionClient("...").
        WithConnectionParams(map[string]interface{}{
            "headers": map[string]string{
                "Authorization": "bearer " + authToken,
            },
        }).
        WithProtocol(graphql.GraphQLWS).
        OnError(func(sc *graphql.SubscriptionClient, err error) error {
            return fmt.Errorf("subscription client error: %v", err)
        })
    defer client.Close()

    datapointsList := []map[string]string{}
    for _, dp := range datapoints {
        datapointsList = append(datapointsList, map[string]string{
            "serialNumber":  dp.DeviceID,
            "channelNumber": dp.ChannelID,
            "datapointId":   dp.Datapoint,
        })
    }

    var sub DataPointsSubscription

    variables := map[string]interface{}{
        "datapointList": datapointsList,
    }

    str, err := client.Subscribe(&sub, variables, func(message []byte, err error) error {
        if err != nil {
            fmt.Println("Subscription error:", err)
            return err
        }
        for _, dp := range sub.Subscription.DataPointsSubscription {
            fmt.Println("Received data point value:", dp.Value)
            fmt.Printf("%+v\n", dp)
        }
        return nil
    }, nil)

    if err != nil {
        return fmt.Errorf("establishing subscription: %v", err)
    }
    fmt.Println(str)

    if err := client.Run(); err != nil {
        return fmt.Errorf("running client: %v", err)
    }
    return nil
}
hgiasac commented 12 months ago

You can use the ContructSubscription function to print and debug the output graphql string

The issue is on the datapointsList variable. You need to define the type of that input variable so the library can reflect it to the equivalent GraphQL input type.

type Foo map[string]interface{}

datapointsList := Foo{ ... }
zdevaty commented 12 months ago

Thank you very much for your quick response! This resolved my problem and now I know how to see the output. Maybe that would be nice to have in the readme? Shall I create a PR?

hgiasac commented 12 months ago

There is a docs section for this, but it isn't detailed. Feel free to improve the README docs.