K6: JSON payload not considered as JSON in POST request

Created on 4 Oct 2017  路  4Comments  路  Source: loadimpact/k6

I have this test (adapter for this issue):

import http from "k6/http";
import { Counter } from "k6/metrics";

export let options = {
    iterations: 1,
    vus: 1,
    insecureSkipTLSVerify: true,
    noConnectionReuse: true,
}


export default function() {
    const headers = {
        'Content-Type': 'application/json'
    };

    const payload = {
        obj: {
           key1 : "10",
           key2 : "10"
       }
   };

    let res = http.post("https://httpbin.org/post", payload, {headers});

    console.log(res.body);
}

This is what I get back:

"args": {},
  "data": "obj=%5Bobject+Object%5D",
  "files": {},
  "form": {},
  "headers": {
    "Accept-Encoding": "gzip",
    "Connection": "close",
    "Content-Length": "23",
    "Content-Type": "application/json",
    "Host": "httpbin.org",
    "User-Agent": "Go-http-client/1.1"
  },
  "json": null,
  "origin": "...",
  "url": "https://httpbin.org/post"

I was expecting the json property to be populated.

I ran the same test with Postman and got back:

{
  "args": {},
  "data": "{\n        \"obj\": {\n           \"key1\" : \"10\",\n           \"key2\" : \"10\"\n       }\n}",
  "files": {},
  "form": {},
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate",
    "Cache-Control": "no-cache",
    "Connection": "close",
    "Content-Length": "80",
    "Content-Type": "application/json",
    "Host": "httpbin.org",
    "Postman-Token": "db1a0f3a-6e90-4795-80a1-c70d5ea85718",
    "User-Agent": "PostmanRuntime/3.0.1"
  },
  "json": {
    "obj": {
      "key1": "10",
      "key2": "10"
    }
  },
  "origin": "...",
  "url": "https://httpbin.org/post"
}

What am I doing wrong here?

Most helpful comment

@jrm2k6

The http.post describes that an object parameter will be query encoded. This is why you receive:

"data": "obj=%5Bobject+Object%5D"

It should work if you encode the object to a JSON string with JSON.stringify.

let res = http.post("https://httpbin.org/post", JSON.stringify(payload), {headers});

Returns:

  "args": {}, 
  "data": "{\"obj\":{\"key1\":\"10\",\"key2\":\"10\"}}", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept-Encoding": "gzip", 
    "Connection": "close", 
    "Content-Length": "33", 
    "Content-Type": "application/json", 
    "Host": "httpbin.org", 
    "User-Agent": "Go-http-client/1.1"
  }, 
  "json": {
    "obj": {
      "key1": "10", 
      "key2": "10"
    }
  }, 
  "origin": "85.194.1.248", 
  "url": "https://httpbin.org/post"
}

All 4 comments

@jrm2k6

The http.post describes that an object parameter will be query encoded. This is why you receive:

"data": "obj=%5Bobject+Object%5D"

It should work if you encode the object to a JSON string with JSON.stringify.

let res = http.post("https://httpbin.org/post", JSON.stringify(payload), {headers});

Returns:

  "args": {}, 
  "data": "{\"obj\":{\"key1\":\"10\",\"key2\":\"10\"}}", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept-Encoding": "gzip", 
    "Connection": "close", 
    "Content-Length": "33", 
    "Content-Type": "application/json", 
    "Host": "httpbin.org", 
    "User-Agent": "Go-http-client/1.1"
  }, 
  "json": {
    "obj": {
      "key1": "10", 
      "key2": "10"
    }
  }, 
  "origin": "85.194.1.248", 
  "url": "https://httpbin.org/post"
}

Yeah, that's the proper way to do it.

@ppcano For me the key takeaway was to do:

  1. JSON.stringify(payload)
  2. wrap the headers in braces

Thanks @ppcano.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

git001 picture git001  路  3Comments

na-- picture na--  路  3Comments

StephenRadachy picture StephenRadachy  路  3Comments

Julianhm9612 picture Julianhm9612  路  4Comments

msznek picture msznek  路  3Comments