◷ Reading Time: 8 minutes
Overview
Here is a breakdown of what we have to do to execute FlexRule services using AWS Lambda.
- Add the Package File and Runtime License File.
- Add Nuget References to Libraries.
- Read the Incoming Request.
- Create a RunTime Engine and Execute your Service.
- Pass the Outputs Back in the Function’s Response.
- Publish your AWS Lambda Function.
- Create an API Gateway for your Function.
- Test your function with Postman.
1. Add the Package File and Runtime License File
Create a folder called Resources in your project and add:
- The FlexRule Designer Package file (e.g. AgeTitle3.frdp).
- Your FlexRule Runtime License file.

2. Add Nuget References to Libraries.
In your project, ensure you have a reference to the latest version of the following libraries.
Amazon.Lambda.APIGatewayEvents
Amazon.Lambda.Core
Amazon.Lambda.Serialization.Json
FlexRule.Runtime
Microsoft.NETCore.App
You can use Nuget Package Manager to add these references.

Add the following using statements to your function class.
using Amazon.Lambda.APIGatewayEvents; using Amazon.Lambda.Core; using FlexRule; using FlexRule.Runner.Commands; using Newtonsoft.Json;
3. Read the Incoming Request.
Use the JsonSerializer to handle JSON input.
// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))]
We’re going to be using an API Gateway to handle requests to our function so we need to start with an empty function handler that takes an APIGatewayProxyRequest
and returns an APIGatewayProxyResponse
.
public APIGatewayProxyResponse FunctionHandler(APIGatewayProxyRequest request, ILambdaContext context) {}
In your function handler call the RunCommand method. We’ll create this method in the next step.
- “
AgeTitle3.frdp
” is the path to the package file we want to use. request.Body
is the string value for inputs into our service.context.Logger
is the logger mechanism to write to AWS CloudWatch Logs.
var result = RunCommand("AgeTitle3.frdp", request.Body, context.Logger);
4. Create a RunTime Engine and Execute your Service.
Add the following method to your function handler class.
public static RunLogicResponse RunCommand(string packagePath, string inputString, ILambdaLogger log)
{
var inputs = (IDictionary<string, object>)Json.Parse(inputString);
var path = Path.Combine(Directory.GetCurrentDirectory(), $"Resources/{packagePath}");
var package = File.ReadAllBytes(path);
var license = File.ReadAllText(Path.Combine(Directory.GetCurrentDirectory(), "Resources/flexrule.license.lic"));
var runtimeFolder = $"{Directory.GetCurrentDirectory()}\\bin";
var runCommand = new RunLogicCommand
{
Runtime = runtimeFolder,
LogicContent = package,
InputValues = inputs,
Cache = true,
};
var logger = new StringBuilder();
var output = new StringBuilder();
var h = new CommandHandler(OutputFactory.CreateString(output), OutputFactory.CreateString(logger));
try
{
h.Execute(new InitLicenseCommand(license));
var result = h.Execute(runCommand);
if (result == null)
throw new FlexRuleException(logger.ToString());
return result;
}
catch (Exception ex)
{
log.Log(ex.Message);
}
return null;
}
5. Pass the Outputs Back in the Function’s Response.
By calling RunCommand()
we should receive back a RunLogicResponse
object which gets assigned to result
.
var result = RunCommand("AgeTitle3.frdp", request.Body, context.Logger);
There are two important variables you need to note.
result.OutParameters
has a list of keys that the service should output.result.Result.Context.VariableContainer
is a Dictionary that holds the output keys and values.
You can use the following snippet to obtain the expected outputs from the service as a list of FlexRule.Json
objects.
var response = result.OutParameters.Select(outParam => result.Result.Context.VariableContainer[outParam] as FlexRule.Json).ToList();
Return this list to the client by packaging it as an APIGatewayProxyResponse
or manipulate it further.
return new APIGatewayProxyResponse
{
StatusCode = (int)HttpStatusCode.OK,
Headers = new Dictionary<string, string> { { "Content-Type", "application/json" } },
Body = JsonConvert.SerializeObject(response),
};
Your completed function handler should look like this:
public APIGatewayProxyResponse FunctionHandler(APIGatewayProxyRequest request, ILambdaContext context)
{
// Create a RunTime Engine and run the service
var result = RunCommand("AgeTitle3.frdp", request.Body, context.Logger);
// Format the outputs as FlexRule Json
var response = result.OutParameters.Select(outParam => result.Result.Context.VariableContainer[outParam] as FlexRule.Json).ToList();
// Return a response through the API Gateway Lambda Proxy
return new APIGatewayProxyResponse
{
StatusCode = (int)HttpStatusCode.OK,
Headers = new Dictionary<string, string> { { "Content-Type", "application/json" } },
Body = JsonConvert.SerializeObject(response),
};
}
6. Publish your AWS Lambda Function.
Ensure that all files in the Resources folder are copied to the output directory by including the following snippet in your project file.
<ItemGroup>
<Content Include="Resources\*.*">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
Use the Upload to AWS Lambda wizard to publish your function.

7. Create an API Gateway for your Function.
Open your function in the AWS Console and click on Add Trigger.

Choose the API Gateway trigger and click

Choose to Create an API with the REST API option.
We’re going to use Open security for this example.
Click on Add.

You should now have an address for your API.

8. Test your Function with Postman
The FlexRule logic in this example takes a person’s age and outputs a word to describe whether they are young or old. The Title
key in the input is currently null
and the service execution will assign an output to this value.
{
"person":{
Age: 23,
Title: null
}
}
Use Postman to send a request to your API Gateway address.
The Body should be set to raw with the inputs for the service.

Click Send.

You should receive a response with your service execution completed and the outputs from the execution.

Optional: Custom DLL Files and FlexRule Extensions
If your business logic uses custom DLL files or FlexRule Extensions:
- Include the DLL files when you create a package in FlexRule Designer.
- Add the
Extension
parameter to your RunLogicCommand.
For example, if you were using the FlexRule Azure Storage Extension, you would use the following snippet.
var runCommand = new RunLogicCommand
{
Runtime = runtimeFolder,
LogicContent = package,
InputValues = inputs,
Cache = true,
Extension = new[] { "FlexRule.Extensions.Storage.AzureStorage.dll" },
};
Optional: Custom Execution Handling
If you want more control over the execution, you can use a different RunCommand()
method which will only give you the output values without the additional functionality required to make this a production-ready solution.
In this scenario you will need to manually implement your own:
- Loading of modules from the package file.
- Loading of custom DLL files required by your service.
- Caching of the FlexRule Runtime Engine creation.
- Event handling.
- Logging of error messages.
private static object RunCommand(string packagePath, string requestBody, ILogger log)
{
try
{
// Initialise license
UserLicense.Key = File.ReadAllText("flexrule.license.lic");
// Create engine
IRuntimeEngine engine;
using (var stream = File.OpenRead(packagePath))
{
var loader = new PackageLoader(stream);
var module = loader.Modules.First();
engine = RuntimeEngine.FromRuleSet(module.Ruleset, module.Entry);
}
// Parse inputs and execute
var inputs = (IDictionary<string, object>) Json.Parse(requestBody);
var result = engine.Run(inputs);
// Get the outputs as Json
var outVariables = engine.Descriptions.ListOutVariableName();
var outputs = outVariables
.Select(outVariable => result.Context.VariableContainer[outVariable] as FlexRule.Json).ToList();
return outputs;
}
catch (Exception ex)
{
log.Log(LogLevel.Error, ex.Message, ex);
return ex.Message;
}
}