Configurando Azure Functions para Acesso a Tabelas do Azure com Padrão Factory e SOLID em TypeScript
Este é o segundo artigo de uma série sobre como configurar Azure Functions para acesso a serviços do Azure utilizando os princípios SOLID (Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, Dependency Inversion). No artigo anterior, abordamos o acesso ao Azure Blob Storage. Neste artigo, focaremos no acesso a tabelas do Azure utilizando o Azure Data Tables.
Passo 1: Configuração do Ambiente
Antes de começar, certifique-se de ter as seguintes dependências instaladas:
npm install @azure/identity @azure/data-tables
OBS: Caso precise ver os Passos 1 ao 3 veja o artigo anterior sobre o tema:
Passo 4: Criando a Fábrica TableServiceClientFactory
Agora vamos criar uma fábrica que utiliza o CredentialProvider
para criar instâncias de TableServiceClient
.
/**
* Factory for creating instances of TableServiceClient.
*/
class TableServiceClientFactory {
private accountUrl: string;
private credentialProvider: CredentialProvider;
/**
* Creates an instance of TableServiceClientFactory.
* @param {string} accountUrl - The account URL for the TableServiceClient.
* @param {CredentialProvider} credentialProvider - The provider for Azure credentials.
*/
constructor(accountUrl: string, credentialProvider: CredentialProvider) {
this.accountUrl = accountUrl;
this.credentialProvider = credentialProvider;
}
/**
* Creates a TableServiceClient instance.
* @returns {TableServiceClient} The TableServiceClient instance.
*/
createTableServiceClient(): TableServiceClient {
const credential = this.credentialProvider.getCredential();
return new TableServiceClient(this.accountUrl, credential);
}
}
Passo 5: Utilizando a Fábrica em uma Azure Function
Vamos ver como podemos utilizar a fábrica para criar uma instância do TableServiceClient
em uma Azure Function. Vamos demonstrar três exemplos: Managed Identity atribuída ao sistema, Managed Identity atribuída ao usuário e Service Principal.
Exemplo 1: Azure Function com Managed Identity Atribuída ao Sistema
import { AzureFunction, Context, HttpRequest } from "@azure/functions";
import { TableServiceClientFactory } from "./TableServiceClientFactory";
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_STORAGETABLE_RESOURCEENDPOINT;
const credentialProvider = new SystemAssignedManagedIdentityCredentialProvider();
const tableServiceClientFactory = new TableServiceClientFactory(accountUrl, credentialProvider);
const tableServiceClient = tableServiceClientFactory.createTableServiceClient();
const list = await tableServiceClient.listTables();
context.res = {
status: 200,
body: list
};
};
export default httpTrigger;
Exemplo 2: Azure Function com Managed Identity Atribuída ao Usuário
import { AzureFunction, Context, HttpRequest } from "@azure/functions";
import { TableServiceClientFactory } from "./TableServiceClientFactory";
import { UserAssignedManagedIdentityCredentialProvider } from "./UserAssignedManagedIdentityCredentialProvider";
/**
* 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_STORAGETABLE_RESOURCEENDPOINT;
const clientId = process.env.AZURE_STORAGETABLE_CLIENTID;
const credentialProvider = new UserAssignedManagedIdentityCredentialProvider(clientId);
const tableServiceClientFactory = new TableServiceClientFactory(accountUrl, credentialProvider);
const tableServiceClient = tableServiceClientFactory.createTableServiceClient();
const list = await tableServiceClient.listTables();
context.res = {
status: 200,
body: list
};
};
export default httpTrigger;
Exemplo 3: Azure Function com Service Principal
import { AzureFunction, Context, HttpRequest } from "@azure/functions";
import { TableServiceClientFactory } from "./TableServiceClientFactory";
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_STORAGETABLE_RESOURCEENDPOINT;
const tenantId = process.env.AZURE_STORAGETABLE_TENANTID;
const clientId = process.env.AZURE_STORAGETABLE_CLIENTID;
const clientSecret = process.env.AZURE_STORAGETABLE_CLIENTSECRET;
const credentialProvider = new ServicePrincipalCredentialProvider(tenantId, clientId, clientSecret);
const tableServiceClientFactory = new TableServiceClientFactory(accountUrl, credentialProvider);
const tableServiceClient = tableServiceClientFactory.createTableServiceClient();
const list = await tableServiceClient.listTables();
context.res = {
status: 200,
body: list
};
};
export default httpTrigger;
Conclusão
Neste artigo, mostramos como configurar uma Azure Function para acesso a tabelas do Azure utilizando diferentes métodos de autenticação aplicando os princípios SOLID. Este design modular facilita a adição de novos métodos de autenticação e a manutenção do código.