How to validate Json Post Request body aginest a schema using Transformation policy?

Mouli Kaku 46 Reputation points
2020-10-27T11:10:33.773+00:00

TIA , I'm receiving fallowing sample data to my AZURE APIM Api as a request body. I want to validate Json body againest schema . how can i do that .

Or atleast how can i make sure my key fields like Userid,firstname and last name does exist in the payload for each record?

Schema :
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"Employees": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"userId": {
"type": "string"
},
"jobTitleName": {
"type": "string"
},
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
},
"preferredFullName": {
"type": "string"
},
"employeeCode": {
"type": "string"
},
"region": {
"type": "string"
},
"phoneNumber": {
"type": "string"
},
"emailAddress": {
"type": "string"
}
},
"required": [
"userId",
"jobTitleName",
"firstName",
"lastName",
"preferredFullName",
"employeeCode",
"region",
"phoneNumber",
"emailAddress"
]
},
{
"type": "object",
"properties": {
"userId": {
"type": "string"
},
"jobTitleName": {
"type": "string"
},
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
},
"preferredFullName": {
"type": "string"
},
"employeeCode": {
"type": "string"
},
"region": {
"type": "string"
},
"phoneNumber": {
"type": "string"
},
"emailAddress": {
"type": "string"
}
},
"required": [
"userId",
"jobTitleName",
"firstName",
"lastName",
"preferredFullName",
"employeeCode",
"region",
"phoneNumber",
"emailAddress"
]
},
{
"type": "object",
"properties": {
"userId": {
"type": "string"
},
"jobTitleName": {
"type": "string"
},
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
},
"preferredFullName": {
"type": "string"
},
"employeeCode": {
"type": "string"
},
"region": {
"type": "string"
},
"phoneNumber": {
"type": "string"
},
"emailAddress": {
"type": "string"
}
},
"required": [
"userId",
"jobTitleName",
"firstName",
"lastName",
"preferredFullName",
"employeeCode",
"region",
"phoneNumber",
"emailAddress"
]
}
]
}
},
"required": [
"Employees"
]
}

Sample data

{
"Employees": [{
"userId": "AAD001",
"jobTitleName": "Developer",
"firstName": "Romin",
"lastName": "Irani",
"preferredFullName": "Romin Irani",
"employeeCode": "E1",
"region": "CA",
"phoneNumber": "408-1234567",
"emailAddress": "romin.k.irani@Stuff .com"
},
{
"userId": "AAD002",
"jobTitleName": "Developer",
"firstName": "Neil",
"lastName": "Irani",
"preferredFullName": "Neil Irani",
"employeeCode": "E2",
"region": "CA",
"phoneNumber": "408-1111111",
"emailAddress": "neilrirani@Stuff .com"
},
{
"userId": "AAD003",
"jobTitleName": "Program Directory",
"firstName": "Tom",
"lastName": "Hanks",
"preferredFullName": "Tom Hanks",
"employeeCode": "E3",
"region": "CA",
"phoneNumber": "408-2222222",
"emailAddress": "tomhanks@Stuff .com"
}
]
}

Thanks
MK

Azure API Management
Azure API Management
An Azure service that provides a hybrid, multi-cloud management platform for APIs.
1,805 questions
0 comments No comments
{count} votes

Accepted answer
  1. Krish G 2,326 Reputation points
    2020-10-27T17:05:22.34+00:00

    @Mouli Kaku , Unfortunately, JSON schema validation against a JSON schema document is not yet supported in API management currently.
    You can upvote in the feedback item here.

    As an alternative (though not very clean, but would work), you can write custom code (C# script) in a set-body inbound policy where you can validate 'JToken' with your logic and throw error if not met. Something like:

       <set-body>@{   
                       var body = context.Request.Body.As<JObject>(preserveContent: true); // Use JArray if request body is array type  
             
                       if (body["userId"] == null) // just an example, adjust as per your json structure  
                       {  
                            throw new Exception("User ID is required");  
                       }  
         
                       // and so on further validation  
             
                       return body.ToString();  
           }</set-body>  
    

    For request which contains array, you can use JArray instead:

       <set-body>@{   
                       var body = context.Request.Body.As<JArray>(preserveContent: true);  
         
                       foreach(var item in body)  
                       {  
                           if (item["userId"] == null) // just an example, adjust as per your json structure  
                           {  
                                 throw new Exception("User ID is required");  
                           }  
                           // and so on further validation  
                       }  
             
                       return body.ToString();  
           }</set-body>  
    

    You can also use context.Request.Body.As<JToken>(preserveContent: true); JToken is base of both JObject and JArray (refer Querying JSON with LINQ).

    For details, refer API Management policy expressions.

    You can make it nicer by collecting all the errors in a list and raise exception with all together as part exception data. To control the returned status, you can use on-error policy to return '400 - bad request' response something like:

       <on-error>  
           <choose>  
               <when condition="@(context.LastError.Message.Contains("Expression evaluation failed")==true)">  
                   <set-status code="400" reason="Bad request" />  
               </when>  
               <otherwise>  
                   <set-status code="500" reason="Error" />  
               </otherwise>  
           </choose>  
           <set-body template="none">@{  
               return context.LastError.Message.Replace("Expression evaluation failed.","").Trim();  
           }</set-body>  
           <base />  
       </on-error>  
    

0 additional answers

Sort by: Most helpful