This post is part of a series

  1. Your Own Serverless Request Bin with Azure Functions
  2. Your Own Serverless Request Bin with Azure Durable Functions (this)

In a previous post, I shared how you can deploy a Serverless Request Bin using Azure Functions. I also shared how I built it using a memory cache as a persistence layer. With that approach, I was able to leverage the new constructor Depending Injection capabilities of Azure Functions that allowed me to use a memory cache across multiple functions. However, the main limitation of that particular method was lack of control of the state lifecycle. I could try to keep the Function App in memory with a timer-triggered function,  however, the platform can change the hosting instance at any given time, which would result in the unpredictable loss of the in-memory state.

In this post, I will show how I leveraged a new feature, currently in preview, of Azure Durable Functions called Durable Entities. These allow me to make my Serverless Request Bin stateful. With this approach, now I can have full control of the lifecycle of the bins.

The Solution

Durable Request Bin Render

As with the previous post, this solution’s code is available on GitHub. However, please consider this a sample solution for personal use. Compared to the previous solution, this time, I used Durable Entities to persist the state of the bins. I kept the rendering to HTML on the Serverless side with DotLiquid templates.

The Function App is composed of three HTTP-triggered functions described as follows:

  • PersistIntoBin: Persists HTTP requests into a particular bin specified as a path parameter.
  • GetBin: Gets the HTTP request history for a particular bin specified as a path parameter.
  • EmptyBin: Deletes the HTTP request history for a particular bin.

Additionally, I introduced a new Durable Entity called RequestBin.cs shown below. As you can see, with very few lines of code, I was able to have a simple and intuitive persistence layer. Durable Entities are persisted in Azure Storage behind the scenes, but all of that is abstracted from us.  

Using Durable Entities

During my refactoring to change the persistence layer from an in-memory cache to Durable Entities, I learned some characteristics of Durable Entities:

  • Simple Programming Model. Durable Entities offer two programming models you can use. The standard function programming model allows you to have a more dynamic set of operations. Alternatively, in the class-based programming model, operations are defined as class methods. I prefer the latter, as calls are type-safe and you get the benefit of IntelliSense, when available, in your development environment.
  • Simple and intuitive persistence layer. The model of the persistence layer is defined with private or public properties of the class containing the Durable Entity function. Each entity instance has a unique identifier assigned via code; this identifier is implicit. Entities are created automatically whenever they are called or signalled for the first time using the unique identifier. By using the class-based programming model, you can invoke defined public methods with type-safe calls to get or mutate the state of an entity. There is no need to design or implement a database, beyond the Durable Entity function class design.
  • Opinionated Programming Model. It is also worth mentioning that while the programming model abstracts a lot of complexity from you, it is also opinionated. You need to be aware that you will need to use the programming model based on the Azure Functions bindings to leverage the abstraction of Durable Entities.

Benefits of the Stateful Serverless Request Bin

The Serverless Request Bin that I showed in my previous post, provides some benefits, including:

  • Owning the Request Bin, thus having no risk of someone else capturing your sensitive HTTP requests.
  • Having a very cost-effective solution, considering the free executions you get and the low cost associated with the corresponding storage.
  • No need of creating a bin in advance, as the platform will create one if the bin identifier is not currently in use.
  • Flexible bin identifiers. You can assign any value you like to the bin identifier, as long as it is not longer than 36 characters, and has no special characters other than a hyphen, underscore or full-stop.
  • Dark Mode ;)

In addition to the above, with the Stateful Serverless Request Bin, we now also get:

  • Full control over the bin lifecycle. Now, with Durable Entities we have full control over the lifecycle of your request bins.

How to Deploy your own

You need an Azure Subscription and access to deploy resources (contributor role) in a resource group. Similar to the previous version, deploying your own instance of the Stateful Serverless Request Bin is very easy. You just need to click on the button below, and this will take you to a page similar to the one shown after.

Deploy To Azure button

At the time of writing, the deploy button option does not allow you to choose the region for a new resource group. Therefore, if you are planning your deployment in a new resource group, it is highly recommended to create the resource group in advance, so you can choose the region for it.

Please read the following section to understand the purpose of each of the settings.

Durable Deploy To Azure

Configuration Options

The configuration options and settings of the Stateful Serverless Request Bin are described in the table below. Some of these options are available only at deployment time, while others are also available after deployment as Application Settings of the Function App created.

Setting

Description

Can it be updated after deployment? 

Directory

Azure Active Directory Tenant that you want to use to deploy the solution

No

Subscription

Azure subscription in which you want to deploy the solution

No

App Name

Used to name the different components of the Serverless Request Bin; including the Function App, the consumption plan, Application Insights, and the Azure Storage account. 

No

App Insights Region

Defines the App Insights region (Given that Application Insights is not available in all regions, choose the closest region to the resource group).

No

Request Bin Renderer

App Setting to configure the Request Bin Renderer to return the Request Bin history to the user. Currently, only Liquid is supported. The Liquid renderer allows you to convert the Request Bin history object to HTML.

Yes

Request Bin Renderer Template

Filename of the Liquid template to use while rendering the request bin history. Currently, only the DarkHtmlRender.liquid template is provided. You can add your own liquid templates to the solution as well.

Yes

Request Bin Max Size

The maximum number of requests to store in the Request Bin.

Yes

Request Body Max Length

The maximum number of characters to read and store from the request body. If a request body is larger than this limit, the body will be truncated.

Yes

Headers to Ignore

Azure Functions add some headers to HTTP requests. If you prefer a cleaner request bin, you can ignore the specified HTTP headers. Specify the headers to ignore as a pipe-delimited list.

Yes

How to use it

Using the Stateful Serverless Request Bin is very easy. The usage operations are the same as the previous version. Once you have successfully deployed the Stateful Serverless Request Bin, you can use in the following:

  • Creating a new Request Bin. Request Bins are created on the fly when the first request to the Request Bin identifier is received. Bin identifiers can be up to 36 characters long and only supports alphabetic characters, numbers, dashes, underscores and full-stops.
  • Sending HTTP Requests for inspection. Send a HTTP request using any method / verb to https://<yourfunctionapp>.azurewebsites.net/<binId>
    e.g. POST https://<yourfunctionapp>.azurewebsites.net/1234567890?a=1&b=2
  • Inspecting the Request Bin history. Retrieve information about a Request Bin history via a GET call including the Bin identifier to https://<yourfunctionapp>.azurewebsites.net/history/<binId>
    e.g. GET https://<yourfunctionapp>.azurewebsites.net/history/1234567890
  • Deleting the Request Bin history. Similarly, delete the history of a Request Bin by including the Bin identifier in a DELETErequest to
    https://<yourfunctionapp>.azurewebsites.net/history/<binId>
    e.g. DELETEhttps://<yourfunctionapp>.azurewebsites.net/history/1234567890

Wrapping Up

Throughout this post and the companion sample code, I’ve shown how you can deploy and configure your own Stateful Serverless Request Bin. I also shared how I built it, leveraging Durable Entities. Feel free to use it for your own development tasks. I hope you found it useful, either as a HTTP request inspector or as sample code. Please feel free to raise issues or contribute by submitting your pull requests on GitHub! :)

Happy coding!

Cross-posted on Deloitte Engineering
Follow me on @pacodelacruz