makeWebRequest: -201 response when sending a POST request containing a JSON array

Former Member
Former Member
I am trying to send a POST request containing a JSON array in the body. The array would contain one or more JSON objects Using the syntax I have tried, the requests aren't successful and I receive a -201 response (INVALID_HTTP_BODY_IN_REQUEST).

I have tried using the syntax in the test, test2 and test3 variables below. I would have provided the full code snippet but it seems to break the forum editor (Error Loading Preview/.

function sendAnswers() {
var url = "https://example.url/" + id + "/answers";

var test = [ {
"a" => "test",
"b" => "test",
"c" => "test"
}, {
"a" => "test",
"b" => "test",
"c" => "test"
} ];

// [{a=>test, b=>test, c=>test}, {a=>test, b=>test, c=>test}]

var test2 = "[{ \"a\": \"test\", \"b\": \"test\", \"c\": \"test\" }]";

// [{ "a":"test", "b":"test", "c": "test" }]

var test3 = "[" +
{ "a" => "test",
"b" => "test",
"c" => "test" }
+ "]";

// [{a=>test, b=>test, c=>test}]

var options = {
:method => Comm.HTTP_REQUEST_METHOD_POST,
:headers => {
"Content-Type" => Comm.REQUEST_CONTENT_TYPE_JSON
}
};

Comm.makeWebRequest(url, test, options, method(:onReceive));
}


var test = [ {
"a" => "test",
"b" => "test",
"c" => "test"
}, {
"a" => "test",
"b" => "test",
"c" => "test"
} ];

// [{a=>test, b=>test, c=>test}, {a=>test, b=>test, c=>test}]

var test2 = "[{ \"a\": \"test\", \"b\": \"test\", \"c\": \"test\" }]";

// [{ "a":"test", "b":"test", "c": "test" }]

var test3 = "[" +
{ "a" => "test",
"b" => "test",
"c" => "test" }
+ "]";

// [{a=>test, b=>test, c=>test}]




Is it possible to POST a JSON request body containing an array with makeWebRequest?
  • Former Member
    Former Member over 8 years ago
    Creating the forum post was all of a sudden successful and included the code snippet and also a second set of test, test2 and test3 variables which I can't now edit out.
  • Former Member
    Former Member over 7 years ago
    did you ever solve this issue??
  • The params parameter must be a Lang.Dictionary. This is covered in the documentation here.

    There is a lot of confusion about what is valid JSON (per ECMA-262) vs what is valid JSON when sending that over HTTP with the application/json content type (I belive this is covered by RFC7159). Most web frameworks agree that the content must be a JSON object, which conveniently maps to a MonkeyC Lang.Dictionary.

    Travis
  • Former Member
    Former Member over 7 years ago
    Hi Travis and Jay,

    Thanks for your comments.

    I can post a Lang.Dictionary object with an array as a value. However, the API I am trying to use expects a JSON array only and not an object with a property that contains an array.

    //Working
    var testParams = {
    "test" => [{
    "a" => "abc",
    "b" => "def",
    "c" => "ghi" }]
    };

    //Desired
    var testParams = [{
    "a" => "abc",
    "b" => "def",
    "c" => "ghi"
    }];

    Would it not be fair to expect that a JSON array is a valid JSON object in this scenario, in agreement with the web frameworks?

    Will
  • Would it not be fair to expect that a JSON array is a valid JSON object in this scenario

    According to all standards I've read, a JSON array is never a JSON object. A JSON object is a collection of key/value pairs. A JSON array is a collection of values.

    This has been a contentious issue in the past, but I think things are settling on the side of requiring JSON text and then defining JSON text as any of the object, array, string, ... I'd have to do some reading to be sure though. That said, there are lots of libraries and frameworks that require JSON object.

    I haven't looked for my old post, but I definitely have filed an issue on this same subject (prior to joining Garmin). I don't believe it is high on the priority list, but I do know that it is there. Unfortunately, for the time being, the only solution for you is to write a service proxy that wraps the response in a JSON object and forwards the response to the client. :(

    Travis

  • Former Member
    Former Member over 7 years ago
    Hi Travis,

    Thanks for your latest response. As you've mentioned, I was planning to create a proxy.

    I guess I was expecting that a JSON array would be classified as an object in a similar way to how the JavaScript 'typeof' function works with native arrays.

    For usability, it's annoying that the SDK/API isn't more forgiving in this case. It would certainly have eased my experience using the SDK and saved time...!

    Will
  • I did a quick test in the simulator and it appears to be processing a JSON array response and passing it through to the application correctly. So, it looks like the team already fixed the issue that I filed..

    I've attached a .zip that includes a python server app and the MonkeyC client to demonstrate. If you run the application under the simulator (be sure to uncheck Settings > Use Device HTTPS Requirements), start the server, and then click the start/stop button or tap the screen of the simulated device, you should see a 200 response code.

    The python code emits the following response (shown on the console)

    200
    Content-Type: application/json
    Content-Length: 108

    [1, 123456789012345, 1.0926535897932, 1092653589793.2, "ab", true, false, null, [], [1, 2, 3], {}, {"1": 2}]


    And the client receives the following (again shown in the console)

    200
    [ 1, 123456789012345L, 1.092654F, 1092653589793.200000, "ab", true, false, null, [], [ 1, 2, 3 ], {}, { "1": 2 } ]


    Are you testing on a device, and if so which device?

    Travis
  • Former Member
    Former Member over 7 years ago
    Thanks for the sample Travis. Apologies as we might have crossed lines, the problem I have is submitting a POST request with a JSON array as the body. As you mentioned before, the SDK currently expects a Lang.Dictionary object to be passed as the 'params' parameter.

    I am testing on a Fenix 5.

    Cheers,
    Will
  • I completely overlooked that you were trying to send an array as the message body. I'll make sure that something is added to the backlog for this.

    Travis
  • Former Member
    Former Member over 7 years ago
    Thanks for your help Travis.