Announcement

Collapse
No announcement yet.

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

Collapse
X
  • Time
  • Show
Clear All
new posts

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

    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/.

    Code:
    
       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?
    Last edited by Travis.ConnectIQ; 01-24-2018, 12:44 AM.

  • #2
    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.
    Last edited by Willii; 07-21-2017, 03:38 AM.

    Comment


    • #3
      did you ever solve this issue??

      Comment


      • #4
        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
        Last edited by Travis.ConnectIQ; 11-16-2017, 10:39 PM.

        Comment


        • #5
          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

          Comment


          • #6
            Originally posted by Willii View Post
            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

            Comment


            • #7
              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

              Comment


              • #8
                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)

                Code:
                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)

                Code:
                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
                Attached Files
                Last edited by Travis.ConnectIQ; 01-02-2018, 10:59 AM.

                Comment


                • #9
                  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

                  Comment


                  • #10
                    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

                    Comment


                    • #11
                      Thanks for your help Travis.

                      Comment


                      • #12
                        Willii,

                        I apologize for not reporting back sooner, but I did file an issue for this. I actually made a request to update {{makeWebRequest}} to allow the caller to provide parameters in addition to the message body. This should allow you to do what you want (put arbitrary json into the body) and what others have asked for (specify request parameters in addition to a body).

                        Travis

                        Comment


                        • #13
                          No problem and thanks for filing the issue Travis. I'm guessing that I can't track it's progress?

                          Comment


                          • #14
                            Correct. There is no public access to our bug tracker. That said, I can tell you that the issue has been backlogged for the time being. While this issue itself isn't complicated, there are many other bits of code that are affected and we want to try to get them fixed in lock-step.

                            Travis

                            Comment


                            • #15
                              Has this issue been resolved? I'm trying to make a POST request to a graphQL API, and while it works as expected in the simulator (the GraphQL service I'm querying returns a 200 response with an appropriate response body) but when I test on-device (FR935), I get back a -201 status and an empty response body. Firmware 11.00 on the 935, and version 4.11.0.11 of Garmin Connect for iPhone/iOS

                              Comment

                              Working...
                              X