Search code examples
websocketgraphqlhasurak6

Receiving error message when trying to connect to GraphQL api over websocket using k6


I'm going to perform a subscription test using k6 for the graphql api that uses Hasura. Here's what I've tried:


import ws from "k6/ws";
import { check } from "k6";

export const myFunc = (url, access_token, id, query) => {
  const headers = {
    Authorization: access_token,
  };

  const res = ws.connect(url, { headers }, function (socket) {
    socket.on("open", function open() {
      console.log(`VU ${__VU}: connected`);

      socket.send(
        JSON.stringify({
          type: "connection_init",
          payload: headers,
        })
      );
      console.log("sending query");
      socket.send(
        JSON.stringify({
          type: "start",
          payload: {
            query: query,
            variables: {
              id,
            }
          },
        })
      );
    });
...

    socket.on("message", function (msg) {
      console.log(`VU ${__VU}: received message: ${msg}`);
      const message = JSON.parse(msg);
      if (message.type == "connection_ack")
        console.log("Connection Established with WebSocket");
      if (message.type == "data") console.log(`Message Received: ${message}`);
    });

...
};

And the logs with error:

INFO[0001] VU 1: connected                               source=console
INFO[0001] sending query                                 source=console
INFO[0001] VU 1: received message: {"type":"ka"}         source=console
INFO[0001] VU 1: received message: {"type":"connection_ack"}  source=console
INFO[0001] Connection Established with WebSocket         source=console
INFO[0001] VU 1: received message: {"type":"ka"}         source=console
INFO[0001] VU 1: received message: {"type":"connection_error","payload":"parsing ClientMessage failed: Error in $: When parsing the record StartMsg of type Hasura.GraphQL.Transport.WebSocket.Protocol.StartMsg the key id was not present."}  source=console

Why am I receiving the key id not present error? I have no idea what that means and couldn't find anything when I searched for it.


Solution

  • When you send a message over established websocket connection, the protocol dictates that you need to send id too. See this link.

    Example payload:

    {
      "id": "1",
      "type":"start",
      "payload": {
        "variables":{},
        "query":"query MyQuery {\n  test {\n    id\n  }\n}\n"
      }
    }
    

    id can be any string decided by the client. When server send the response back, it will contain the same id. With parsing ClientMessage failed error message, Hasura is complaining that it cannot find the id.