apideck-libraries/postman-to-k6

GraphQL Support

Kpizzle opened this issue · 8 comments

Hi There,

I just came across this watching the office hours episode regarding this and loved the workflow shown by Tim.

I'd like to implement this type of workflow for my team so whipped up a small API to test out the workflow and starting planning for our system design, however I seem to be getting some issues once I try and run the k6. This scipt runs fine, but fails to actually hit the endpoints and tests fails.

We/I am using a graphQL API for this proof of concept and wondered if that's the issue, that the postman-to-k6 tool doesn't support graphQL API's/tests coming from postman? I can see that k6 does support graphQL.

Any help would be great.

Thanks.

Hi @Kpizzle

If there is an error, could you share it?

When you run K6, you can add a debug option
k6 run --http-debug="full k6-script.js

This will give you some insights on the actual HTTP requests being made.

Hi @Kpizzle ! Nice that you caught us on k6 Office Hours. :)

I can confirm that k6 does support GraphQL. I'm also happy to help out from the k6 side if you can share more details about the issue. In the meantime, here's a previous k6 Office Hours episode about using k6 with GraphQL.

Hi @thim81

Here is the output from running the above. FYI, I'm just running a local graphQL server that just returns an array of user objects.

     script: social-app-k6.js
     output: -

  scenarios: (100.00%) 1 scenario, 1 max VUs, 10m30s max duration (incl. graceful stop):
           * default: 1 iterations for each of 1 VUs (maxDuration: 10m0s, gracefulStop: 30s)

INFO[0003] Request:
POST /graphql HTTP/1.1
Host: localhost:4000
User-Agent: k6/0.36.0 (https://k6.io/)
Content-Length: 78
Accept-Encoding: gzip

{"query":"{\r\nusers {\r\n  _id,\r\n  firstName,\r\n  lastName\r\n    }\r\n}"}  group= iter=0 request_id=6ea522ca-0e44-4ffe-75d2-9f8ca078a663 scenario=default source=http-debug vu=1
INFO[0003] Response:
HTTP/1.1 400 Bad Request
Content-Length: 53
Connection: keep-alive
Content-Type: application/json; charset=utf-8
Date: Mon, 28 Feb 2022 22:19:12 GMT
Etag: W/"35-rkfaW07yp80JIwkYI6hoaXIO3bI"
Keep-Alive: timeout=5
X-Powered-By: Express

{"errors":[{"message":"Must provide query string."}]}  group= iter=0 request_id=6ea522ca-0e44-4ffe-75d2-9f8ca078a663 scenario=default source=http-debug vu=1

I'm now seeing the error in the output and stating that no query string is being sent? Here is the script generated with the converter.


import "./libs/shim/core.js";
import "./libs/shim/urijs.js";

export let options = { maxRedirects: 4 };

const Request = Symbol.for("request");
postman[Symbol.for("initial")]({
  options,
  environment: {
    env: "http://localhost:4000/graphql"
  }
});

export default function() {
  postman[Request]({
    name: "GetAllUsers",
    id: "38648e95-0590-4cd5-84ad-841b366564d0",
    method: "POST",
    address: "{{env}}",
    data:
      '{"query":"{\\r\\nusers {\\r\\n  _id,\\r\\n  firstName,\\r\\n  lastName\\r\\n    }\\r\\n}"}',
    post(response) {
      pm.test("Status code is 200", function() {
        pm.response.to.have.status(200);
      });
    }
  });
}

Please let me know if there is anything else I can do to help? I can get the code into a repo with with all the postman files etc if needed.

Hi @nicolevanderhoeven!

Thanks for the reply! I'm aware that k6 works with GraphQL, We've been looking into using it already, but it's the postman-to-k6 converter that doesn't seem to be playing nice with graphQL? I've replied to @thim81 hoping he can help.

@thim81 I think I've found the issue!

After some tinkering with the error message, and exporting the API test from postman itself, and checking the k6 test. I noticed that the postman[Request]({}) object didn't have the headers typically being sent with postman.

So if you just add

   headers: {
      "Content-Type": "application/json"
    },

The test works perfectly! I'm not sure if this is a bug/defect, an oversight or wasn't just needed before. It'd be great if you could confirm this fix?

Thanks.

@Kpizzle I had similar issue in the past, and to overcome this we added the --k6-params option to postman-to-k6.

Some explanation:

  • Postman does not explicitly set common "headers", like content-type/accept (see github) when exporting the Postman collection.
  • postman-to-k6 takes the Postman collection as the source and converts the JSON Postman collection into K6, so if the Postman collection JSON has no content-type set, the Content-Type header will not be part of the K6 requests.
  • K6 uses by default uses application/x-www-form-urlencoded if no content-type header is set.

Possible solutions:

  • Set the desired header explicitly in Postman, so that it is part of the Postman collection when exported
  • Manually add the K6 params options
  • Pass it postman-to-k6 using the --k6-params

An example of an "k6-params.json":

{
  "maxRedirects": 6,
  "headers": {
    "Content-Type": "application/json"
  }
}

And then use it like this when converting your postman collection to K6 scripts.

postman-to-k6 collection.json --k6-params k6-params.json -o k6-script.js

Thanks for reminding me of this, I've created a Q&A for this in the Discussions section, so that users that run into similar issues, can find the possible solutions. Feel free to review the answers and correc/add if something is missing.

If you are OK, with the above answers, feel free to close the issue.

Hi @thim81

Thanks very much! Yes, that solved my problem. I just added the header to the test before exporting from postman and the rest worked flawlessly.

Thanks for you help!