6 Replies Latest reply on Mar 20, 2017 9:25 AM by rvaaraniemi RSS
    deanm Newbie

    Respond with JSON without using an InfoTable Template

    I have a number of services in my solution that are invoked via RESTful POST requests from an external application.  The services must respond with a set of values.  Each service responds with a different set of values (and as the solution matures over time, these responses could become more diverse and more numerous).

     

    The response from the services must be in a JSON format.  I've set up the services to have the result type = JSON, but everything I try generates an error with the service.  Here is a simplified example of what may be included in the response:

     

    {

        "siteId": <string>,        // calculated by the service

        "areaName": <string>,      // pulled from a different Thing

        "percentFailed": <number>  // calculated by the service

    }

     

    If I create this structure as a JavaScript object, I was expecting to use result = JSON.stringify(responseObj) to create a JSON object that could be used for the response.  The service crashes when converting the object to JSON just prior to finishing (i.e. the ThingWorx behind-the-scenes code can't convert it to a JSON response type).

     

    If I use the same as above, but set the result type to STRING in the service composer window, it doesn't crash, but the response contains lots of extraneous information.  For example:

     

    {\"dataShape\":{

      \"fieldDefinitions\":{

        \"result\":{

          \"name\":\"result\",

          \"description\":\"\",

          \"baseType\":\"STRING\",

          \"ordinal\":0,

          \"aspects\":{}}}},

          \"rows\":[{

            \"result\":\"{

              \\\"siteId\\\":\\\"Site-47\\\",

              \\\"areaName\\\":\\\"Area 51\\\",

              \\\"percentFailed\\\":\\\"23.75\\\"

            }\"

          }]

         }

       }

    }

    }

     

    This is generating additional unnecessary parsing in the requesting application.  I would prefer to only have the result object returned.

     

    I'm of the understanding that I can create an InfoTable Template for the response, temporarily instantiate a table, populate it, and the return the table.  This will generate a JSON response.  However, I'd like to avoid this approach if possible because now I'm defining the response in two places (the template and the JavaScript).  Every time a developer needs to change the response, both places need to be updated.  Additionally, the solution would end up with numerous InfoTable Templates (one per service) that will need to be maintained.  This feels like a poor design choice to me and will increase future development unnecessarily.

     

    What I'd like is to find a solution that doesn't require an InfoTable (uses only JavaScript objects) and returns a JSON object that only contains the response values.

     

    Any ideas are greatly appreciated!

      • Re: Respond with JSON without using an InfoTable Template
        maneeshr Explorer

        Hi Dean,

         

        You can use inbuilt function ToJSON  which is provided under snippets  to convert output of service into JSON objetct/format.

          • Re: Respond with JSON without using an InfoTable Template
            deanm Newbie

            Maneesh,

             

            Thanks for your response, but that method is on ThingWorx objects, such as InfoTables, but is not standard JavaScript methods, so it will only work with objects that I've also defined in ThingWorx as a Template or DataShape and then instantiated within the service code.  I don't want to have to do that dual maintenance of objects (both as a ThingWorx object and as a JavaScript data structure) because that quickly becomes a support nightmare when the customer asks for changes to a response and those changes need to be implemented in multiple places.  (Note that I am dealing with responses from a third party customer's software, as opposed to my own company's software, so I have less control over what may be needed/desired on the responses in the future.)

             

            I would prefer to only have to define the structure once in the JavaScript service and then return that structure as a JSON object without a bunch of extraneous ThingWorx wrappers on the JSON.

              • Re: Respond with JSON without using an InfoTable Template
                maneeshr Explorer

                Hi Dean,

                What i understand is that you want to use standard JavaScript function to convert the output of Thingworx services which may be Infotable/String/Number into  JSON object.

                what you can do is , add the result of service into an array and then convert that array into JSON object using standard function JSON.stringify(array).

                 

                 

                Thanks

                  • Re: Respond with JSON without using an InfoTable Template
                    deanm Newbie

                    Maneesh,

                     

                    That is exactly what I did.  The resulting response is the nested structure I shared in the original post.  There is a lot of extraneous ThingWorx information in the structure that the requesting application then needs to traverse to get to the actual response.  We are trying to avoid that additional traversing logic by only receiving the pertinent structure in the response.

              • Re: Respond with JSON without using an InfoTable Template
                jamesm Creator

                Result  type JSON is the one you want. I created a simple service to test this:

                 

                result = {

                    "siteId": "hello",

                    "areaName": "test",

                    "percentFailed": "hi"

                }

                 

                with output type JSON, and I tested in postman to get the expected result:

                 

                {"percentFailed": "hi","areaName": "test","siteId": "hello"}



                Note: *THIS WILL NOT SHOW UP FROM WITHIN THE COMPOSER IF YOU TEST THE SCRIRPT. THE TEST SCRIPT WINDOW IN COMPOSER WILL NOT  DISPLAY JSON OR XML BASE TYPES. YOU NEED TO TEST THIS IN POSTMAN OR SOME  OTHER TOOL*

                 

                One note: If you are  returning a JSON array, it will be wrapped in an object of the following structure

                 

                result = [1,2,3]

                 

                will return

                 

                {

                     "array": [1,2,3]

                }

                 

                There is a workaround for this, but it's a bit messy and depends what you are trying to do. I have a bug report open on this on Jira -- PSPT-2985.

                  • Re: Respond with JSON without using an InfoTable Template
                    rvaaraniemi Explorer

                    Hi James,

                     

                    Are there any updates on this extra "array" addition bug? I just experienced the same issue? I'm trying to output a "pure" JSON array without any extra stuff around it and this messes up my plans.

                     

                    Can you tell me anything more about the workaround? I'm creating my array manually with "var jsonObject = [];" and adding stuff there using push(). I tested the infotable.ToJSON but that created too much extra stuff for my taste.

                     

                    My TW version: 7.2.5-b56

                     

                    BR,

                    Risto