I am using this code for azure APIM policies
<set-variable name="newRequest" value="@(context.Request.Body?.As<JObject>(preserveContent: true))" />
<set-variable name="insured-id" value="@(context.Request.MatchedParameters["id"].Last())" />
<send-request mode="new" timeout="20" response-variable-name="id" ignore-error="false">
<set-url>@($"https://api.dev.com/external/workRequest/get")</set-url>
<set-method>POST</set-method>
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<set-header name="Authorization" exists-action="override">
<value>@(context.Request.Headers.GetValueOrDefault("Authorization","scheme param"))</value>
</set-header>
<set-body>{"insuredId": @($"{(string)context.Variables["insured-id"]}")}</set-body>
</send-request>
<choose>
<when condition="@((int)((IResponse)context.Variables["id"]).Body.As<JObject>(preserveContent: true)["workRequests"]["entityStatus"]== 1)">
<return-response response-variable-name="id">
<set-status code="400" reason="VOID" />
<set-header name="Content-Type" exists-action="override">
<value>application/json</value></set-header>
<set-body>{"statusCode": 400,
"message": "The insured cannot be voided as it is currently attached with one or more active workrequest"}</set-body>
</return-response>
</when>
<otherwise />
</choose>
I am taking an insuredId from template parameter of the API operation where I am implementing the APIM policies & using it in the set-body, this will list all the workrequests for that insuredId.
The payload for the POST is something like
{"insuredId": template-parameter}
When returning a response getting 500 error. How to resolve this. The condition which is there is okay. I am suspecting error in set body.
Also how to check whether a particular string like "entityStatus": 1
is there in the response of api, because this https://api.dev.com/external/workRequest/get
url will give a list of workrequest records in array form
The request to https://api.dev.com/external/workRequest/get
is failing:
"message": "POST request to 'https://api.dev.com/external/workRequest/get' has been sent, result stored in 'id' variable.",
"statusCode": "MethodNotAllowed",
"statusReason": "Method Not Allowed",
The response of failed request is stored in the variable id
.
But this response not return any json document in the body.
Therefore, the following expression is failing and an error 500 is returned:
"(int)((IResponse)context.Variables[\"id\"]).Body.As<JObject>(preserveContent: true)[\"workRequests\"][\"entityStatus\"]== 1",
The message body is not a valid JSON. Unexpected character encountered while parsing value: <. Path '', line 0, position 0.\r\n at Newtonsoft.Json.JsonTextReader.ParseValue()\r\n at Microsoft.WindowsAzure.ApiManagement.Proxy.Runtime.Configuration.Models.SyncOnlyDepthTrackingJsonTextReader.Read()\r\n at Newtonsoft.Json.Linq.JObject.Load(JsonReader reader, JsonLoadSettings settings)\r\n at Gateway.Pipeline.IO.JObjectFormatter.Format(JsonTextReader jsonTextReader)\r\n at Gateway.Pipeline.IO.JsonConverter.Convert[T](Stream stream, Encoding encoding, ILog log, Object conversionSettings)\r\n at Microsoft.WindowsAzure.ApiManagement.Proxy.Gateway.MessageBody.As[T](Boolean preserveContent)
Please check the supported http-methods of https://api.dev.com/external/workRequest/get
.
Maybe your code has to changed to GET
:
<send-request mode="new" timeout="20" response-variable-name="id" ignore-error="false">
<set-url>@($"https://api.dev.com/external/workRequest/get")</set-url>
<set-method>GET</set-method>
UPDATE for question from comments:
thanks, I resolved the issue. The when condition I was using was syntactically wrong as I had a response in the form of array list { "workRequests": [{ "id": 154, "workRequestNumber": "W000154", "insured": {"id": 268,"uri": null, "entityStatus": 1,"workRequestStatus": 0,"entityStatus": 1 },....
It's better to create a new Stackoverflow Question instead of doing it in comments. Maybe that's what you asking for:
Request body:
{
"workRequests": [
{
"id": 154,
"workRequestNumber": "W000154",
"insured": {
"id": 268,
"uri": null,
"entityStatus": 1,
"workRequestStatus": 0
}
},
{
"id": 154,
"workRequestNumber": "W000154",
"insured": {
"id": 268,
"uri": null,
"entityStatus": 0,
"workRequestStatus": 0
}
}
]
}
Response:
A variable is assigned with a true
value of any entityStatus
equals 1
.
The choose
policy returns a 400 with entityStatus
equals true
.
Policy:
<inbound>
<base />
<set-variable name="isEntityStatusEqualsOne" value="@{
var body = (JObject)context.Request.Body.As<JObject>(true);
JArray workrequests = body["workRequests"] as JArray;
for(int i = 0; i < workrequests.Count; i++)
{
JObject workrequest = workrequests[i] as JObject;
var entityStatus = ((JValue)workrequest["insured"]["entityStatus"]).Value<int>();
if(entityStatus == 1)
{
return true;
}
}
return false;
}" />
<choose>
<when condition="@(context.Variables.GetValueOrDefault<bool>("isEntityStatusEqualsOne") == true)">
<return-response response-variable-name="id">
<set-status code="400" reason="VOID" />
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<set-body>{"statusCode": 400,
"message": "The insured cannot be voided as it is currently attached with one or more active workrequest"}</set-body>
</return-response>
</when>
<otherwise>
<return-response response-variable-name="id">
<set-status code="200" reason="OK" />
</return-response>
</otherwise>
</choose>
</inbound>