Home > Enterprise >  Parsing JSON Array in Azure APIM policy
Parsing JSON Array in Azure APIM policy

Time:09-12

I need some help Parsing JSON Array in Azure APIM policy. My input to my API is a JSON Array but I want the output of the API to be JSON without the "[]", I just can't get the policy to remove them.

Here is the JSON Array input to my API:

[
 {
   "id": "myId",
   "topic": "myTopic",
   "subject": "/apis/test;Rev=1",
   "data": {
     "resourceUri": "myResourceUri"
   },
   "eventType": "Microsoft.ApiManagement.APIUpdated",
   "dataVersion": "1",
   "metadataVersion": "1",
   "eventTime": "2022-09-08T14:22:46.7708654Z"
 }
]

But I would like the Output of the policy to remove the square brackets [], like this:

{
   "id": "myId",
   "topic": "myTopic",
   "subject": "/apis/test;Rev=1",
   "data": {
     "resourceUri": "myResourceUri"
   },
   "eventType": "Microsoft.ApiManagement.APIUpdated",
   "dataVersion": "1",
   "metadataVersion": "1",
   "eventTime": "2022-09-08T14:22:46.7708654Z"
}

Here is my policy (which I copied from a tutorial and manipulated):

<policies>
    <inbound>
        <base />
        <set-variable value="@(context.Request.Headers["Aeg-Event-Type"].Contains("SubscriptionValidation"))" name="isEventGridSubscriptionValidation" />
        <set-variable value="@(context.Request.Headers["Aeg-Event-Type"].Contains("Notification"))" name="isEventGridNotification" />
        <choose>
            <when condition="@(context.Variables.GetValueOrDefault<bool>("isEventGridSubscriptionValidation"))">
                <return-response>
                    <set-status code="200" reason="OK" />
                    <set-body>@{
                          var events = context.Request.Body.As<string>(); 
                          JArray a = JArray.Parse(events);
                          var eventGridData = a.First["data"];
                          var validationCode = eventGridData["validationCode"];
                          var jOutput =
                             new JObject(
                                new JProperty("validationResponse", validationCode)
                             );
                        return jOutput.ToString();
                    }</set-body>
                </return-response>
            </when>
            <when condition="@(context.Variables.GetValueOrDefault<bool>("isEventGridNotification"))">
                <send-one-way-request mode="new">
                    <set-url>https://hooks.slack.com/services/mySlackHandle</set-url>
                    <set-method>POST</set-method>
                    <set-body>@{  
                        var events = context.Request.Body.As<string>(); 
            JArray a = JArray.Parse(events);
            var eventGridData = a.First["data"];
            var song = eventGridData["song"];
            return new JObject( 
                new JProperty("text", String.Format(" {1}", 
                 song, a))).ToString();   
                    }</set-body>
                </send-one-way-request>
                <return-response>
                    <set-status code="200" reason="OK" />
                </return-response>
            </when>
        </choose>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

ANY HELP GREATLY APPRECIATED! Extra points if you can remove the reference to "song", which I cannot without breaking the policy...

CodePudding user response:

You have to convert your json array to a json object like this:

<set-body>@(Newtonsoft.Json.JsonConvert.SerializeObject((JObject)(context.Request.Body.As<JArray>(preserveContent: true))[0]))</set-body>

Your can remove the serialization if you want to keep the body as a json object. But the trick is to capture the body as a JArray and then use the [0] to choose the "first" object in the array and thereafter convert your body to a JObject.

  • Related