Everything you need to know to integrate your Azure Service Bus with your Azure Function using the Factory Pattern and TypeScript
Welcome to the sixth chapter of our exciting series on integrating Azure Functions with Azure services using the powerful SOLID principles! We’ve already explored how to connect to Azure Storage, Azure Key Vault, and Azure Web PubSub. Now, get ready to dive into the fascinating world of Azure Service Bus! 📬
- Don’t lose your head configuring TypeScript Azure Functions for Access to Azure Key Vault and…
- Configuring Azure Functions for Efficient Azure Storage Queue Access with SOLID and Factory Pattern…
What is Azure Service Bus?
Azure Service Bus is a fully managed messaging platform that allows communication between different parts of a distributed system, such as cloud applications, services, and devices. It offers a robust solution for integrating systems and ensuring reliable message delivery.
Key Components of Azure Service Bus
1. Queues
Queues in Azure Service Bus allow asynchronous communication between different parts of an application. Messages are stored in a queue until the recipient is ready to process them, ensuring ordered and reliable delivery.
2. Topics and Subscriptions
Topics enable a publish-subscribe (pub/sub) model, where messages published to a topic are delivered to multiple subscriptions. Each subscription can apply filters to receive only relevant messages, allowing flexible routing.
3. Rules and Filters
Subscriptions can use rules and filters to define specific criteria for message routing. This allows advanced customization of which messages are delivered to which subscriptions.
Advantages of Azure Service Bus
1. Reliable Delivery
Azure Service Bus ensures the delivery of messages with durability and fault tolerance. It persistently stores messages until they are successfully processed by the receiver.
2. Scalability
With horizontal scalability, Azure Service Bus can handle large volumes of messages and transactions, supporting systems of any size.
3. Security
Azure Service Bus integrates with Microsoft Entra ID and offers robust authentication and access control, ensuring that only authorized users and applications can send and receive messages.
4. Flexibility
With support for different communication patterns, such as queues, topics, and subscriptions, Azure Service Bus can be adapted to a wide variety of scenarios and system architectures.
Use Cases
1. Integration of Heterogeneous Systems
Azure Service Bus facilitates communication between systems developed in different languages and platforms, providing smooth and efficient integration.
2. Asynchronous Processing
It allows the decoupling of application components, where tasks can be queued and processed asynchronously, improving system efficiency and resilience.
3. Complex Message Routing
With topics and subscriptions, Azure Service Bus can manage complex message routing scenarios, ensuring that the right information is delivered to the right recipients.
Azure Service Bus is a powerful tool for communication and integration of distributed systems, offering reliable delivery, scalability, security, and flexibility. Whether integrating heterogeneous systems, managing asynchronous processing, or handling complex message routing, Azure Service Bus is a robust and efficient choice for cloud messaging solutions.
Step 1: Environment Setup
Before you start, make sure you have the following dependencies installed:
npm install @azure/identity @azure/keyvault-secrets
Note: If you need to see Steps 2 to 3, refer to the previous article on the topic:
Como Configurar o Azure Blob Service Client Aplicando os Princípios SOLID em uma Azure Function com…
Step 4: Setting Up the Factory for Secret Clients
Now, let’s create a factory to instantiate the ServiceBusClient using our CredentialProvider.
import { ServiceBusClient } from "@azure/service-bus";
/**
* Factory for creating instances of ServiceBusClient.
*/
class ServiceBusClientFactory {
private fullyQualifiedNamespace: string;
private credentialProvider: CredentialProvider;
/**
* Creates a new instance of ServiceBusClientFactory.
* @param {string} fullyQualifiedNamespace - The fully qualified namespace of the Azure Service Bus.
* @param {CredentialProvider} credentialProvider - The credential provider to be used.
*/
constructor(fullyQualifiedNamespace: string, credentialProvider: CredentialProvider) {
this.fullyQualifiedNamespace = fullyQualifiedNamespace;
this.credentialProvider = credentialProvider;
}
/**
* Creates an instance of ServiceBusClient.
* @returns {ServiceBusClient} A configured instance of ServiceBusClient.
*/
createServiceBusClient(): ServiceBusClient {
const credential = this.credentialProvider.getCredential();
return new ServiceBusClient(this.fullyQualifiedNamespace, credential);
}
}
Step 5: Implementing in Azure Function
Now let’s see how we can integrate this structure into an Azure Function, demonstrating each authentication method.
Example 1: Azure Function with System-assigned Managed Identity
import { AzureFunction, Context, HttpRequest } from "@azure/functions";
import { ServiceBusClientFactory } from "./ServiceBusClientFactory";
import { SystemAssignedManagedIdentityCredentialProvider } from "./SystemAssignedManagedIdentityCredentialProvider";
/**
* Azure Function using System-Assigned Managed Identity.
* @param {Context} context - The function context.
* @param {HttpRequest} req - The HTTP request.
* @returns {Promise<void>} A promise that resolves when the function is complete.
*/
const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
const fullyQualifiedNamespace = process.env.AZURE_SERVICEBUS_FULLYQUALIFIEDNAMESPACE;
const credentialProvider = new SystemAssignedManagedIdentityCredentialProvider();
const serviceClientFactory = new ServiceBusClientFactory(fullyQualifiedNamespace, credentialProvider);
const serviceClient = serviceClientFactory.createServiceBusClient();
// Use the serviceClient for operations with Service Bus
context.res = {
body: "Azure Function using System-Assigned Managed Identity for Access to Service Bus"
};
};
export default httpTrigger;
Example 2: Azure Function with User-assigned Managed Identity
import { AzureFunction, Context, HttpRequest } from "@azure/functions";
import { ServiceBusClientFactory } from "./ServiceBusClientFactory";
import { UserAssignedManagedIdentityCredentialProvider } from "./UserAssignedManagedIdentityCredentialProvider";
/**
* Azure Function using User-Assigned Managed Identity.
* @param {Context} context - The function context.
* @param {HttpRequest} req - The HTTP request.
* @returns {Promise<void>} A promise that resolves when the function is complete.
*/
const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
const fullyQualifiedNamespace = process.env.AZURE_SERVICEBUS_FULLYQUALIFIEDNAMESPACE;
const clientId = process.env.AZURE_SERVICEBUS_CLIENTID;
const credentialProvider = new UserAssignedManagedIdentityCredentialProvider(clientId);
const serviceClientFactory = new ServiceBusClientFactory(fullyQualifiedNamespace, credentialProvider);
const serviceClient = serviceClientFactory.createServiceBusClient();
// Use the serviceClient for operations with Service Bus
context.res = {
body: "Azure Function using User-Assigned Managed Identity for Access to Service Bus"
};
};
export default httpTrigger;
Example 3: Azure Function with Service Principal
import { AzureFunction, Context, HttpRequest } from "@azure/functions";
import { ServiceBusClientFactory } from "./ServiceBusClientFactory";
import { ServicePrincipalCredentialProvider } from "./ServicePrincipalCredentialProvider";
/**
* Azure Function using Service Principal.
* @param {Context} context - The function context.
* @param {HttpRequest} req - The HTTP request.
* @returns {Promise<void>} A promise that resolves when the function is complete.
*/
const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
const fullyQualifiedNamespace = process.env.AZURE_SERVICEBUS_FULLYQUALIFIEDNAMESPACE;
const tenantId = process.env.AZURE_SERVICEBUS_TENANTID;
const clientId = process.env.AZURE_SERVICEBUS_CLIENTID;
const clientSecret = process.env.AZURE_SERVICEBUS_CLIENTSECRET;
const credentialProvider = new ServicePrincipalCredentialProvider(tenantId, clientId, clientSecret);
const serviceClientFactory = new ServiceBusClientFactory(fullyQualifiedNamespace, credentialProvider);
const serviceClient = serviceClientFactory.createServiceBusClient();
// Use the serviceClient for operations with Service Bus
context.res = {
body: "Azure Function using Service Principal for Access to Service Bus"
};
};
export default httpTrigger;
Conclusion
🎉 You’ve learned how to configure Azure Functions to access Azure Service Bus using various authentication techniques and applying SOLID an Clean Code principles! Our modular and scalable approach makes maintaining and enhancing the code easier.
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:
- Please consider clapping and following the writer! 👏
- Follow us X | LinkedIn | YouTube | Discord
- Visit our other platforms: In Plain English | CoFeed | Differ
- More content at Stackademic.com
Everything you need to know to integrate your Azure Service Bus with your Azure Function using the… was originally published in Stackademic on Medium, where people are continuing the conversation by highlighting and responding to this story.