Friday, May 26, 2017

Validating JSON arrays when the payload is sent as a query parameter with WSO2 ESB

In my previous post, I explained how JSON payloads can be validated when it's sent as a query parameter. Using the same Synapse configuration without doing any changes, we will see how JSON arrays can be validated by tweaking the JSON schema.

Assume that my requirement is to send a JSON array as a query parameter as shown below.
http://localhost:8280/jsonAPI/jsonapi?jsonPayload=[{"getQuote": {"request": {"symbol": "WSO2"}}},{"getQuote": {"request": {"symbol": "MSFT"}}}]

Create an API using the same configuration which we have used in the previous post.

   <api context="/jsonAPI" name="jsonAPI">
        <resource methods="GET" protocol="http" uri-template="/jsonapi">
            <inSequence>
                <property expression="$url:jsonPayload"
                    name="jsonKeyValue" scope="default" type="STRING"/>
                <payloadFactory media-type="json">
                    <format>$1</format>
                    <args>
                        <arg evaluator="xml" expression="get-property('jsonKeyValue')"/>
                    </args>
                </payloadFactory>
                <validate>
                    <schema key="conf:/schema/StockQuoteSchema.json"/>
                    <on-fail>
                        <payloadFactory media-type="json">
                            <format>{"Error":"$1"}</format>
                            <args>
                                <arg evaluator="xml" expression="$ctx:ERROR_MESSAGE"/>
                            </args>
                        </payloadFactory>
                        <respond/>
                    </on-fail>
                </validate>
                <respond/>
            </inSequence>
        </resource>
    </api>

The StockQuoteSchema.json which you have created under the path conf:/schema/StockQuoteSchema.json should be written in the following format.

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "type": "array",
    "items": [{
        "getQuote": {
            "type": "object",
            "properties": {
                "request": {
                    "type": "object",
                    "properties": {
                        "symbol": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "symbol"
                    ]
                }
            },
            "required": [
                "request"
            ]
        }
    }],
    "required": [
        "getQuote"
    ]
}

Note the text marked in blue. In the previous example, when a simple JSON payload was sent, the value of the type was set to object whereas in this scenario, since it's handling JSON arrays, it should be set to array.

On the other hand, since your JSON payload is sending an array, the schema should list elements to be checked inside a block called items with the JSON body wrapped inside square brackets i.e.; [] as highlighted above. 

So once the above configuration is done, and the GET request is sent to the API, you should see the following output if everything goes well.

[
  {
    "getQuote": {
      "request": {
        "symbol": "WSO2"
      }
    }
  },
  {
    "getQuote": {
      "request": {
        "symbol": "MSFT"
      }
    }
  }
]

No comments: