Logic Apps Standard: A clever hack to apply JSON schema versioning for JSON message validation (Part 2)

Logic Apps Standard: A clever hack to apply JSON schema versioning for JSON message validation (Part 2)

6 minutes

This article was originally published on LinkedIn.

Introduction

JSON schema validation in Logic Apps has always been a challenge, because the JSON schemas can be uploaded either to Integration Account or the Logic Apps Standard Artifacts folder, but none of the actions that might validate the incoming JSON file is able to refer to that location. As a result, the Parse JSON action which validates JSON messages either contained the full schema definition or might point to a storage account blob location where the JSON schema resides.

In my previous article – Logic Apps Standard: A clever hack to use JSON schemas in your Artifacts folder for JSON message validation (Part 1) – I have showed a clever way to read the contents of a JSON schema in the Logic Apps Standard Artifacts folder, and use it to validate an incoming message with the Parse JSON action.

Implementing this functionality also gives other interesting possibilities. One of them is applying a clever way to do JSON schema versioning. This article explores the what, the why and the how.

Context

At my current client we use the VB-PUO data exchange standard to exchange messages with both internal and external parties and organizations.

To give a bit of context: This standard has been developed to provide a uniform approach for data exchange between asset management parties and pension administrators/pension administration organizations. The standard consists of documentation, JSON schemas, and example messages. (GitHub – dma61/VBPUOdsk).

Twice a year, a new version is released, containing adjustments in the messaging standard and its JSON schemas. This standard demands that – any organization that uses it – must support the current and previous version. 

To do so, versioning must be implemented in all layers of your integrations within the integration landscape. 

This article will mainly focus on validating the incoming message to different versions of a schema. But of course, version support goes beyond only validation, e.g.:

  • Do you need to implement versioning in the API that is in front of your workflow?
  • If validation succeeds, how do you transform different versions of a source message to a target message?
  • When using functions to transform: How should you set up your models to support multi versions of a message?
  • How do you handle versioning on outgoing messages with many subscribers that use different versions?

All good questions. Please let me know if you want me to dive into specific topics.

The What / Why

In the previous article I have described how it is possible to retrieve a JSON schema from the Logic Apps Standard Artifacts/Schemas folder and use it for message validation.

Now, there might be requirements that state that support for different versions of a JSON schema is needed and that an incoming message should be validated against the proper version of a schema before being processed. Such requirements are common, especially if your integration landscape implements market standards for message exchange like EDI X12, Edifact, HL7, etc.

How do you achieve this by using workflows? 

The How

Normally some of the options to include multi schema support / validation in Logic App Consumption or Standard might be:

  • Have multiple versions of the receive workflow where each one uses a different schema. Expose these workflows though an API in API Management. Based on the version the request gets routed to the proper Logic Apps Standard workflow (e.g. message property, HTTP header, API path or anything else). This workflow uses the built-in HTTP trigger schema or the Parse JSON action containing the proper version of the JSON schema.
  • Or, have a single receive workflow that determines the used schema version based on the previously mentioned parameters. A Switch action with a branch for each version is implemented that validates the message. The following picture shows this example: 

One can use branches for different versions of a schema in order to validate the message.
One can use branches for different versions of a schema in order to validate the message.

Even though the above examples might give maintenance overhead or add more complexity to your workflows, they are perfectly valid approaches.

In addition to my previous article, I wanted to show how that solution can be used to provide a simpler way to validate multiple schemas.

Step 1: Have multiple versions of a schema in your Artifacts/Schemas folder

The starting point of the multiple JSON schema validation solution is to have multiple versions of a specific message in your Artifacts/Schemas folder in Logic Apps Standard as shown in the following picture:

As you can see, the message has three schema versions:

  • 001.00
  • 001.01
  • 002.00

Versioning is done through the file name with a specific convention [source].[message type].[version].json. Any convention can be used, if the schema version exists in the file name and reflects the proper version format.

Step 2: The magic happens (again) with the CSharpScriptCode action

In part 1, the CSharpScriptCode action was introduced to retrieve a JSON schema from the Artifacts folder.

The C# code for the schema is somewhat adjusted to support versioning, as the following code snippet shows:

// Add the required libraries
#r "Newtonsoft.Json"
#r "Microsoft.Azure.Workflows.Scripting"
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Microsoft.Extensions.Logging;
using Microsoft.Azure.Workflows.Scripting;
using Newtonsoft.Json.Linq;

public static async Task<Result> Run(WorkflowContext context, ILogger log)
{
  // Get the body of the set "version" variable action. This action can use a HTTP header, a property in the incoming JSON or whatsoever to dynamically determine the schema version.
  JToken actionInputs = (await context.GetActionResults("Set_variable_afdDefinitionVersion").ConfigureAwait(false)).Inputs;


  // Replace the spaces in the schema version with dots, so the schema can be resolved in the schemas directory.
  var schemaVersion = actionInputs["value"]?.ToString().Replace(" ", ".", StringComparison.Ordinal);

  // Set location where schema can be found. Also note that the schemaVersion variable is used in the file name, this way it retrieves the proper schema
  var home = Environment.GetEnvironmentVariable("HOME");
  var path = Path.Combine(home, "site", "wwwroot", "artifacts", "schemas", $"sivi.feedback.{schemaVersion}.json");

  // Read the contents of the file and return it to the workflow.
  var json = await File.ReadAllTextAsync(path).ConfigureAwait(false);
  var schema = JObject.Parse(json);

  return new Result
  {
    Schema = schema   // Logic Apps sees this as a JSON object
  };
}

public class Result
{
  public JObject Schema { get; set; }
}

Step 3: Validate that schema exists

As explained previously, you should validate that the schema file exists in Logic Apps Standard and take proper action if it cannot be found.

To do so:

  • Place a switch action directly after the CSharpScriptCode action, that runs both on Succeeded and Failed of the previous C# action.
  • The check should be as follows: 
  • Besides the empty default branch, there should be a branch that checks on a specific code “InvokeFunctionFailed“.
  •  This branch throws an exception if the CSharpScriptCode couldn’t find the schema or failed for any other reason.
actions('Get_json_schema')?['code']

The above will look like this:

Step 4: Validate with the Parse JSON action

I also explained this in part 1. The content of the JSON schema definition is retrieved, and can then be used in the Parse JSON action as follows:

@{outputs('Get_json_schema')['body']['schema']}

Validation failures are handled by the Switch action that comes next. 

Nevertheless, by making some minor adjustments in both naming of the JSON schemas in the Artifacts folder and the code that is used by the CSharpScriptCode action, multi-version validation is supported with only a single Parse JSON action.

Conclusion

Message versioning is a complex topic, and validating a message with the proper schema version is part of that. Hopefully this article gives you some handy insights into how to simplify the validation process.


Leave a Reply

Your email address will not be published. Required fields are marked *