6.4 Azure Functions in Custom Connectors and Data Transformation
Key Takeaways
- Azure Functions commonly back custom connectors when no existing REST API exists, or when orchestration across multiple systems is required.
- Function keys map to the connector's API Key authentication type; Microsoft Entra ID-secured Functions map to OAuth 2.0.
- The Create from Azure service import path can auto-detect and configure OAuth 2.0 for an Entra ID-secured Function App.
- Complex, multi-source, or reusable-library data transformations belong in Azure Function code; simple field renames or reformatting are better handled by the connector's transformation policy template.
- Function code should be tested independently before layering the connector's OpenAPI definition and Test-tab check on top of it.
When the API a custom connector needs to expose does not already exist — or exists but does not return data in a shape Power Platform can consume cleanly — the two tools a PL-400 developer reaches for are Azure Functions and data-transformation code.
Developing an Azure Function for a Custom Connector
An Azure Function is frequently the backing implementation behind a custom connector rather than a pre-existing third-party API, because it lets a developer write exactly the logic a solution needs and expose it as a lightweight HTTP endpoint. Typical reasons a Function backs a connector instead of the connector calling an existing API directly:
- No existing REST API for the required operation — the Function is the API, purpose-built for this connector.
- Orchestration — the Function needs to call multiple downstream systems (a legacy database, a third-party service, another Azure resource) and return one consolidated result to the flow or app.
- Server-side business logic that should not live in a flow's expression language or a canvas app's Power Fx — validation rules, calculations, or logic that needs a full programming language and its ecosystem of libraries.
An HTTP-triggered Azure Function exposed to a custom connector is built like any other HTTP trigger function: it defines an HTTP-triggered entry point (via [Function("...")] and HttpTrigger in the isolated worker model for .NET, or the equivalent trigger binding in function.json for other languages), reads parameters from the query string, route, or request body, and returns an HttpResponseData/IActionResult with a JSON payload and status code. Two securing choices matter for the connector's Security tab:
- Function keys — the simplest option; the key is supplied as a header or query parameter and maps to the connector's API Key authentication type.
- Microsoft Entra ID — the Function App is registered as an app registration and requires a bearer token; the connector uses OAuth 2.0 authentication, and this is the option the Create from Azure service import path can auto-detect and configure.
Before wiring the Function into a connector, developers typically test it independently — locally with Azure Functions Core Tools and VS Code, or against the deployed Function App using a tool like the built-in Test/Run blade in the Azure portal or an HTTP client — to confirm the request/response contract before layering the connector's OpenAPI definition and Test-tab connector test on top of it.
Transforming Data for Power Platform Consumption
Even when a connector fronts a real, working API, the data it returns is not always shaped the way flows and apps expect. Data transformation closes that gap, and there are two levels at which it can happen:
- Inside the Azure Function or backing service itself. Because you control the Function's code, this is the natural place to reshape complex payloads — converting XML responses to JSON, flattening deeply nested objects into a flat structure a canvas app's gallery can bind to directly, renaming fields to friendlier names, or aggregating multiple upstream calls into a single response object. This approach is best when the transformation logic is complex, needs external libraries, or has to combine data from more than one source.
- Inside the connector's policy layer, using the advanced request/response transformation policy template described in the previous section. This is best for lightweight, self-contained reshaping — renaming a field, reformatting a timestamp, or restructuring a response envelope — where writing and redeploying Function code would be overkill for the amount of change needed.
Choosing Between the Two
| Scenario | Prefer |
|---|---|
| Complex business logic, multiple downstream calls, needs a full language/ecosystem | Azure Function code |
| Simple field rename, reshape, or format conversion on an existing API's payload | Policy template transformation |
| No existing API for the operation at all | Azure Function (the Function is the API) |
| Need to keep transformation logic reusable across connectors without redeploying code | Policy template transformation |
The exam-relevant judgment call is recognizing that not every transformation needs a redeployed Function — a maker-visible connector-level policy is often the lighter-weight, more maintainable fix, while genuinely new logic or multi-system orchestration belongs in Function code.
Using the Connector in Flows, Apps, and ALM
Once a custom connector — Azure Function-backed or otherwise — is built, tested, and shared, it appears in the connector picker in Power Automate (+ New step > search for the connector's name) and as a data source in Power Apps, exactly like any built-in connector. A maker adds a connection (supplying credentials per the configured authentication type) and the connector's actions and triggers become available with the same friendly labels, dropdowns, and dynamic content the developer configured in the Definition tab.
Two ALM details matter once that flow or app needs to move between environments:
- The connector belongs in a solution. Adding the custom connector as a solution component, alongside the flow or app that consumes it, is what lets it travel through a dev → test → production pipeline instead of only existing in the environment where it was authored.
- Flows should reference the connector through a connection reference, not a hard-coded personal connection. A connection reference is a solution component that points to a connection without embedding a specific maker's credentials. When the flow is imported into a new environment, an admin rebinds the connection reference to a connection appropriate for that environment (a service account, for example) instead of the flow silently depending on the original maker's personal sign-in. This is the standard, exam-relevant reason connection references exist: they decouple "which connector operation does this flow call" from "whose credentials does it run as," which is essential once a custom connector-backed flow needs to be deployed and administered outside the maker's own environment.
An Azure Function App backing a custom connector is secured with a function key rather than Microsoft Entra ID. Which connector authentication type maps to this?
A connector's backing API returns a response that only needs a single field renamed before a flow can consume it. What is generally the more maintainable fix?