Try for free Book a demo

Decoding Logic App Dilemmas: Nested JSON schema validation

Microsoft Azure

8 Mins Read

Nested JSON schema validation in Logic App

Welcome again to another Decoding Logic App Dilemmas: Solutions for Seamless Integration! This time we selected a problem related to a few tips and tricks I have been writing Message validation inside Logic Apps or JSON schema validation.

One of our previous dilemmas addressed this complex topic: Decoding Logic App Dilemmas: How to validate if a JSON property is not an empty string? , of course, describing and addressing a different problem.

Nested JSON schema validation in Logic App

In this blog post, we want to see how nested JSON schema validation is supported inside Logic Apps and, more precisely, how to get the correct error message from the nested JSON schema validation.

Applying Subschemas conditionally is something that is accepted and specified on the JSON Schema specification. You can read more here: Applying Subschemas Conditionally. One of the available options is to use the if, then, and else keywords to allow the application of a subschema based on the outcome of another schema, much like the if/then/else constructs you’ve probably seen in traditional programming languages.

  • If if is valid, then must also be valid (and else it is ignored.) If if is invalid, else must also be valid (and then it is ignored).
  • If then or else is not defined, if behaves as if they have a value of true.
  • If then and/or else appear in a schema without if, then and else are ignored.

Problem: How can the correct error message be obtained from the nested JSON schema validation?

In this scenario, we will be sending a simple JSON message:

{
"address": [
{
"contact": {
"firstName": "Sandro",
"lastName": "Pereira"
},
"type": "bill"
}
]
}

If the type property is bill then firstName is a mandatory field. Otherwise, none of the fields (first and last name) are required.

We can accomplish that by using the following JSON Schema:

{
"type": "object",
"properties": {
"address": {
"type": "array",
"items": {
"type": "object",
"properties": {
"contact": {
"type": "object",
"properties": {
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
}
},
"required": []
},
"type": {
"type": "string"
}
},
"required": [
"contact",
"type"
]
}
}
},
"if": {
"properties": {
"address": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {
"const": "bill"
}
}
}
}
}
},
"then": {
"properties": {
"address": {
"type": "array",
"items": {
"type": "object",
"properties": {
"contact": {
"required": [
"firstName"
],
"properties": {
"firstName": {
"type": "string"
}
}
}
}
}
}
}
},
"else": {
"properties": {
"address": {
"type": "array",
"items": {
"type": "object",
"properties": {
"contact": {
"required": [],
"properties": {}
}
}
}
}
}
}
}

Solution: Using a Parse JSON action

However, despite we can successfully save the Logic App, we cannot apply this JSON Schema and perform a Schema validation inside the Request > When a HTTP request is received trigger.

Step 1 - Using a Parse JSON action

Otherwise, the Logic App will not be triggered, and we will end up receiving the following error message:

{
   "error": {
       "code": "TriggerInputSchemaMismatch",
       "message": "The input body for trigger 'request' of type 'Request' did not match its schema definition. Error details: 'Invalid type. Expected Object but got String.'."
    }
}

Step 2 - Using a Parse JSON action

So, for me, that means the if… then… else keywords are not supported inside the Request > When a HTTP request is received trigger. However, we can work around this limitation by removing the schema from the trigger:

Step 3 - Using a Parse JSON action

And add a Parse JSON action, where we set the Body of the trigger to be the Content of this action and set the above JSON Schema on the Schema property:

Step 4 - Using a Parse JSON action

To test this validation and to get the output result of this validation, we can add a Response action on our business logic inside the Logic App and configure them to have the Body property as: @{outputs(‘Parse_JSON’)}

Step 5 - Using a Parse JSON action

Of course, in real scenarios, our logic should have implemented a good error-handling capability. For that, you can check this free whitepaper: Logic Apps Consumption – How to get the Logic App error detail message guide. But for this proof-of-concept, let’s Configure the run after setting of our Response action:

Step 6 - Using a Parse JSON action

To save everything, click Done.

Step 7 - Using a Parse JSON action

Now if I try my Logic App with a valid message, I will end up receiving the same message in the response, which means that the Parse JSON successfully validated my message:

Step 8 - Using a Parse JSON action

Otherwise, I will get a detailed error message describing the actual error.

Step 9 - Using a Parse JSON action

if I would like to receive only a short message describing the error, then I could modify the Body of the Response action to be:

  • if(empty(outputs(‘Parse_JSON’)[‘errors’]),outputs(‘Parse_JSON’),outputs(‘Parse_JSON’)[‘errors’][0][‘childErrors’][0][‘message’])

Now if I try this with an invalid message, I will get the following error message:

Step 10 - Using a Parse JSON action

Advantages of this solution

The main advantages of this solution are:

  • Simplicity: The advantage of this approach is that I don’t need to implement several, or complex, conditions to validate these Subschemas. We can use the OpenJS Foundation standard specification for JSON Schema directly inside Logic Apps.
  • No extra services: we don’t need any extra Azure Services like Azure Functions to perform these schema validations.

Disadvantages of this solution

The main disadvantages of this solution are:

  • Implementation of a good error handling capability: if we can consider it as a disadvantage, it is that you need to implement error handling in order to get the correct error message back.
  • Pattern keyword is not supported: not all OpenJS Foundation standard specifications are supported. A good example is the Pattern keyword, which means that not all the scenarios you may have can be implemented with this approach.

Above, I explained how we can obtain the correct error message from the nested JSON schema validation using out-of-the-box Logic Apps features (i.e., without the need for other Azure Services).

Below, I explain what, for me, will be the best approach to accomplish that and be valid for all scenarios.

Solution: Using an Azure Function to perform JSON Schema validation

Again, unfortunately, at the moment, Logic Apps does not support all the OpenJS Foundation standard specifications regarding JSON Schema definitions. However, we can quickly work around that limitation and implement what I think will be the best solution by using another service of the Azure Integration Services: Azure Functions.

You can find and use my JSON Schema Validation Function that I released on my personal blog. This JSON Schema Validation Function is a simple function that allows you to validate your JSON message against a JSON Schema, enabling you to specify constraints on the structure of instance data to ensure it meets the requirements.

The function receives a JSON payload with two properties:

  • The JSON message in the json property.
  • And the JSON Schema in the jsonSchema property.

Example:

{
"json": {
"address": [
{
"contact": {
"firstName": "Sandro",
"lastName": "Pereira"
},
"type": "bill"
}
]
},
"jsonSchema": {
"type": "object",
"properties": {
"address": {
"type": "array",
"items": {
"type": "object",
"properties": {
"contact": {
"type": "object",
"properties": {
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
}
},
"required": []
},
"type": {
"type": "string"
}
},
"required": [
"contact",
"type"
]
}
}
},
"if": {
"properties": {
"address": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {
"const": "bill"
}
}
}
}
}
},
"then": {
"properties": {
"address": {
"type": "array",
"items": {
"type": "object",
"properties": {
"contact": {
"required": [
"firstName"
],
"properties": {
"firstName": {
"type": "string"
}
}
}
}
}
}
}
},
"else": {
"properties": {
"address": {
"type": "array",
"items": {
"type": "object",
"properties": {
"contact": {
"required": [],
"properties": {}
}
}
}
}
}
}
}
}

You then just need to call this function inside your Logic App:

Step 1 - Using Azure Function to perform JSON Schema validation

Now if we try this with some sample messages, we will see that:

  • If we send a valid message, we will get a 200 OK

Step 2 - Using Azure Function to perform JSON Schema validation

  • If we send an invalid message, we will get a 200 OK with an error message – this is because I designed the solution for that. Ideally, this should be different.

Step 3 - Using Azure Function to perform JSON Schema validation

Advantages of this solution

The main advantages of this solution are that:

  • Works with all scenarios: The advantage of this approach is that it supports all the OpenJS Foundation standard specifications for JSON Schema so that it will work for all possible scenarios, including using pattern keywords.
  • The correct error message is simple to obtain: The Azure Function is responsible for providing a good, simple, and standard structure for the error message; in this case, we can easily obtain it without the need to implement complex logic inside the Logic Apps.

Disadvantage of this solution

The main disadvantage of this solution is that:

  • We need to buy and use an external service: we need an Azure Function resource to accomplish this, which sometimes means extra costs depending on the number of executions and service plan you will use.

The goal of this new series is to find common problems that people are facing with Logic Apps, either on StackOverflow, Logic App forums, Azure Logic Apps Microsoft Q&A, or any other source – feel free to provide ideas/problems you would like to be addressed – and provide a solution or solutions to that problem. At least, I will add my point of view to address that issues. Of course, there may be other solutions; feel free to comment if that’s the case.

I hope you find this content useful and stay tuned for more Decoding Logic App Dilemmas.

This article was published on Jul 7, 2023.

Related Articles