hasura / go-graphql-client

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

Can't get graphql-ws protocol working #125

Closed chuongle closed 7 months ago

chuongle commented 7 months ago

Here is the current code that I have

subscriptionClient = graphql.NewSubscriptionClient("ws://localhost:8888/graphql").
    WithConnectionParams(map[string]interface{}{
        "headers": map[string]string{
            "Authorization": "Bearer " + token,
        },
    }).
    WithProtocol(graphql.GraphQLWS).
    OnConnected(func() {
        log.Println("Connected")
    }).
    OnDisconnected(func() {
        log.Println("Disconnected")
    }).
    OnError(func(sc *graphql.SubscriptionClient, err error) error {
        log.Println(err.Error())
        return err
    })

_, err := subscriptionClient.Subscribe(query, nil, func(data []byte, errValue error) error {
    if errValue != nil {
        // handle error
        // if returns error, it will failback to `onError` even
        return errValue
    }

    // handle data here

    return nil
})

if err != nil {
    log.Fatal("Error when subscribe: ", err)
}

err = subscriptionClient.Run()

if err != nil {
    log.Fatal("Error Starting Subscription: ", err)
} else {
    log.Println("No error here")
    os.Exit(1)
}

When I tried to run this code, I got the error failed to read JSON message: failed to get reader: received close frame: status = StatusCode(4403) and reason = "Forbidden". But if I switched to the subscription transport protocol, it's working normally. I can assure the server side (not Hasura) is working because I have a NodeJS application subscribe to the server using graphql-ws protocol. Can someone give me some clue where I can try to debug this?

hgiasac commented 7 months ago

You should check your server logs for more context. The 4403 status code means the client has failed to authorize the credential. Or the connection parameters are in a different structure.

       // different format per different server specs
    WithConnectionParams(map[string]interface{}{
        "headers": map[string]string{
            "Authorization": "Bearer " + token,
        },
    })

We can't reproduce it unless you can share the framework name (graphql-ws, apollo,...) or service of the GraphQL server. Do you implement the graphql server with

chuongle commented 7 months ago

@hgiasac to be specific, we are using this recipe because we want to support both graphql-ws and subscription-transport-ws.

I will try to debug some more on the server side

hgiasac commented 7 months ago

@chuongle you should find the code line with close(4403, 'Forbidden') on the server code. Because the custom auth is implemented by your team. The exit code is emitted manually.

In this auth recipe, if the server authorizes on onConnect or onSubscribe events, it will return the status code 4500. The status code 4403 is emitted after upgrading the WebSocket connection.

chuongle commented 7 months ago

@hgiasac Sorry for the delay. thank you for some of the hints. I was able to identify the issue. I will close this now.