O Sertão será Cloud

Configuring Azure Functions for Efficient Azure Storage Queue Access with SOLID and Factory Pattern…

Configuring Azure Functions for Efficient Azure Storage Queue Access with SOLID and Factory Pattern in TypeScript

This is the third article in a series on configuring Azure Functions for accessing Azure services using SOLID principles (Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, Dependency Inversion). In previous articles, we covered accessing Azure Blob Storage and Azure Tables. In this article, we will focus on accessing Azure queues using Azure Storage Queue. If you’re interested in integrating Azure Table Storage, check out the article below

Configuring Azure Functions for Azure Table Access with SOLID and Factory Pattern in TypeScript

Step 1: Setting Up the Environment

Before starting, make sure you have the following dependencies installed:

npm install @azure/identity @azure/storage-queue

NOTE: If you need to see Steps 1 to 3, please refer to the previous article on the subject.

Como Configurar o Azure Blob Service Client Aplicando os Princípios SOLID em uma Azure Function com…

Step 4: Creating the QueueServiceClientFactory

We will implement a factory to create instances of QueueServiceClient based on the selected credential provider.

import { QueueServiceClient } from "@azure/storage-queue";

/**
* Factory for creating instances of QueueServiceClient.
*/
class QueueServiceClientFactory {
private accountUrl: string;
private credentialProvider: CredentialProvider;

/**
* Creates an instance of QueueServiceClientFactory.
* @param {string} accountUrl - The account URL for the QueueServiceClient.
* @param {CredentialProvider} credentialProvider - The provider for Azure credentials.
*/
constructor(accountUrl: string, credentialProvider: CredentialProvider) {
this.accountUrl = accountUrl;
this.credentialProvider = credentialProvider;
}

/**
* Creates a QueueServiceClient instance.
* @returns {QueueServiceClient} The QueueServiceClient instance.
*/
createQueueServiceClient(): QueueServiceClient {
const credential = this.credentialProvider.getCredential();
return new QueueServiceClient(this.accountUrl, credential);
}
}

Step 5: Using the Factory in an Azure Function

Let’s see how we can use the factory to create an instance of QueueServiceClient within an Azure Function. We’ll demonstrate three examples: System-assigned managed identity, User-assigned managed identity, and Service Principal.

Example 1: Azure Function with System-assigned Managed Identity

import { AzureFunction, Context, HttpRequest } from "@azure/functions";
import { QueueServiceClientFactory } from "./QueueServiceClientFactory";
import { SystemAssignedManagedIdentityCredentialProvider } from "./SystemAssignedManagedIdentityCredentialProvider";

/**
* Azure Function triggered by an HTTP request.
* @param {Context} context - The Azure Function context object.
* @param {HttpRequest} req - The HTTP request object.
*/
const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
const accountUrl = process.env.AZURE_STORAGEQUEUE_RESOURCEENDPOINT;
const credentialProvider = new SystemAssignedManagedIdentityCredentialProvider();
const queueServiceClientFactory = new QueueServiceClientFactory(accountUrl, credentialProvider);

const queueServiceClient = queueServiceClientFactory.createQueueServiceClient();
const queueClient = queueServiceClient.getQueueClient(queueName);
await queueClient.sendMessage("Hello World!");

context.res = {
status: 200,
body: { text: "menssage sent" }
};
};

export default httpTrigger;

Example 2: Azure Function with User-assigned Managed Identity

import { AzureFunction, Context, HttpRequest } from "@azure/functions";
import { QueueServiceClientFactory } from "./QueueServiceClientFactory";
import { SystemAssignedManagedIdentityCredentialProvider } from "./SystemAssignedManagedIdentityCredentialProvider";

/**
* Azure Function triggered by an HTTP request.
* @param {Context} context - The Azure Function context object.
* @param {HttpRequest} req - The HTTP request object.
*/
const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
const accountUrl = process.env.AZURE_STORAGEQUEUE_RESOURCEENDPOINT;
const credentialProvider = new SystemAssignedManagedIdentityCredentialProvider();
const queueServiceClientFactory = new QueueServiceClientFactory(accountUrl, credentialProvider);

const queueServiceClient = queueServiceClientFactory.createQueueServiceClient();
const queueClient = queueServiceClient.getQueueClient(queueName);
await queueClient.sendMessage("Hello World!");

context.res = {
status: 200,
body: { text: "menssage sent" }
};
};

export default httpTrigger;

Example 3: Azure Function with Service Principal

import { AzureFunction, Context, HttpRequest } from "@azure/functions";
import { QueueServiceClientFactory } from "./QueueServiceClientFactory";
import { ServicePrincipalCredentialProvider } from "./ServicePrincipalCredentialProvider";

/**
* Azure Function triggered by an HTTP request.
* @param {Context} context - The Azure Function context object.
* @param {HttpRequest} req - The HTTP request object.
*/
const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
const accountUrl = process.env.AZURE_STORAGEQUEUE_RESOURCEENDPOINT;
const tenantId = process.env.AZURE_STORAGEQUEUE_TENANTID;
const clientId = process.env.AZURE_STORAGEQUEUE_CLIENTID;
const clientSecret = process.env.AZURE_STORAGEQUEUE_CLIENTSECRET;
const credentialProvider = new ServicePrincipalCredentialProvider(tenantId, clientId, clientSecret);
const queueServiceClientFactory = new QueueServiceClientFactory(accountUrl, credentialProvider);

const queueServiceClient = queueServiceClientFactory.createQueueServiceClient();
const queueClient = queueServiceClient.getQueueClient(queueName);
await queueClient.sendMessage("Hello World!");

context.res = {
status: 200,
body: { text: "menssage sent" }
};
};

export default httpTrigger;

Conclusion

In this article, we discussed how to configure and use Azure Functions to interact with Azure queues, following SOLID principles using the Factory Pattern. By modularizing credential acquisition and service client creation, we facilitate code maintenance and scalability in diverse authentication scenarios.

References

Início Rápido – Criar uma conexão de serviço no aplicativo de funções por meio do portal do Azure

Stackademic 🎓

Thank you for reading until the end. Before you go:


Configuring Azure Functions for Efficient Azure Storage Queue Access with SOLID and Factory Pattern… was originally published in Stackademic on Medium, where people are continuing the conversation by highlighting and responding to this story.