Dapr Invoke output binding for Azure Functions
The Dapr invoke output binding allows you to invoke another Dapr application during a function execution.
For information on setup and configuration details of the Dapr extension, see the Dapr extension overview.
Example
A C# function can be created using one of the following C# modes:
Execution model | Description |
---|---|
Isolated worker model | Your function code runs in a separate .NET worker process. Use with supported versions of .NET and .NET Framework. To learn more, see Develop .NET isolated worker process functions. |
In-process model | Your function code runs in the same process as the Functions host process. Supports only Long Term Support (LTS) versions of .NET. To learn more, see Develop .NET class library functions. |
The following example demonstrates using a Dapr invoke output binding to perform a Dapr service invocation operation hosted in another Dapr-ized application. In this example, the function acts like a proxy.
[FunctionName("InvokeOutputBinding")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "invoke/{appId}/{methodName}")] HttpRequest req,
[DaprInvoke(AppId = "{appId}", MethodName = "{methodName}", HttpVerb = "post")] IAsyncCollector<InvokeMethodParameters> output,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
var outputContent = new InvokeMethodParameters
{
Body = requestBody
};
await output.AddAsync(outputContent);
return new OkResult();
}
The following example creates a "InvokeOutputBinding"
function using the DaprInvokeOutput
binding with an HttpTrigger
:
@FunctionName("InvokeOutputBinding")
public String run(
@HttpTrigger(
name = "req",
methods = {HttpMethod.GET, HttpMethod.POST},
authLevel = AuthorizationLevel.ANONYMOUS,
route = "invoke/{appId}/{methodName}")
HttpRequestMessage<Optional<String>> request,
@DaprInvokeOutput(
appId = "{appId}",
methodName = "{methodName}",
httpVerb = "post")
OutputBinding<String> payload,
final ExecutionContext context)
In the following example, the Dapr invoke output binding is paired with an HTTP trigger, which is registered by the app
object:
const { app, trigger } = require('@azure/functions');
app.generic('InvokeOutputBinding', {
trigger: trigger.generic({
type: 'httpTrigger',
authLevel: 'anonymous',
methods: ['POST'],
route: "invoke/{appId}/{methodName}",
name: "req"
}),
return: daprInvokeOutput,
handler: async (request, context) => {
context.log("Node HTTP trigger function processed a request.");
const payload = await request.text();
context.log(JSON.stringify(payload));
return { body: payload };
}
});
The following examples show Dapr triggers in a function.json file and PowerShell code that uses those bindings.
Here's the function.json file for daprInvoke
:
{
"bindings":
{
"type": "daprInvoke",
"direction": "out",
"appId": "{appId}",
"methodName": "{methodName}",
"httpVerb": "post",
"name": "payload"
}
}
For more information about function.json file properties, see the Configuration section.
In code:
using namespace System.Net
# Input bindings are passed in via param block.
param($req, $TriggerMetadata)
# Write to the Azure Functions log stream.
Write-Host "Powershell InvokeOutputBinding processed a request."
$req_body = $req.Body
$invoke_output_binding_req_body = @{
"body" = $req_body
}
# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name payload -Value $invoke_output_binding_req_body
Push-OutputBinding -Name res -Value ([HttpResponseContext]@{
StatusCode = [HttpStatusCode]::OK
Body = $req_body
})
The following example shows a Dapr Invoke output binding, which uses the v2 Python programming model. To use daprInvoke
in your Python function app code:
import logging
import json
import azure.functions as func
app = func.FunctionApp()
@app.function_name(name="InvokeOutputBinding")
@app.route(route="invoke/{appId}/{methodName}", auth_level=dapp.auth_level.ANONYMOUS)
@app.dapr_invoke_output(arg_name = "payload", app_id = "{appId}", method_name = "{methodName}", http_verb = "post")
def main(req: func.HttpRequest, payload: func.Out[str] ) -> str:
# request body must be passed this way "{\"body\":{\"value\":{\"key\":\"some value\"}}}" to use the InvokeOutputBinding, all the data must be enclosed in body property.
logging.info('Python function processed a InvokeOutputBinding request from the Dapr Runtime.')
body = req.get_body()
logging.info(body)
if body is not None:
payload.set(body)
else:
logging.info('req body is none')
return 'ok'
Attributes
In the in-process model, use the DaprInvoke
attribute to define a Dapr invoke output binding, which supports these parameters:
Parameter | Description | Can be sent via Attribute | Can be sent via RequestBody |
---|---|---|---|
AppId | The Dapr app ID to invoke. | ✔️ | ✔️ |
MethodName | The method name of the app to invoke. | ✔️ | ✔️ |
HttpVerb | Optional. HTTP verb to use of the app to invoke. Default is POST . |
✔️ | ✔️ |
Body | Required. The body of the request. | ❌ | ✔️ |
Annotations
The DaprInvokeOutput
annotation allows you to have your function invoke and listen to an output binding.
Element | Description | Can be sent via Attribute | Can be sent via RequestBody |
---|---|---|---|
appId | The app ID of the application involved in the invoke binding. | ✔️ | ✔️ |
methodName | The name of the method variable. | ✔️ | ✔️ |
httpVerb | Post or get. | ✔️ | ✔️ |
body | Required. The body of the request. | ❌ | ✔️ |
Configuration
The following table explains the binding configuration properties that you set in the code.
Property | Description | Can be sent via Attribute | Can be sent via RequestBody |
---|---|---|---|
appId | The app ID of the application involved in the invoke binding. | ✔️ | ✔️ |
methods | Post or get. | ✔️ | ✔️ |
body | Required. The body of the request. | ❌ | ✔️ |
The following table explains the binding configuration properties that you set in the function.json file.
function.json property | Description | Can be sent via Attribute | Can be sent via RequestBody |
---|---|---|---|
appId | The app ID of the application involved in the invoke binding. | ✔️ | ✔️ |
methodName | The name of the method variable. | ✔️ | ✔️ |
httpVerb | Post or get. | ✔️ | ✔️ |
body | Required. The body of the request. | ❌ | ✔️ |
The following table explains the binding configuration properties for @dapp.dapr_invoke_output
that you set in your Python code.
Property | Description | Can be sent via Attribute | Can be sent via RequestBody |
---|---|---|---|
app_id | The app ID of the application involved in the invoke binding. | ✔️ | ✔️ |
method_name | The name of the method variable. | ✔️ | ✔️ |
http_verb | Set to post or get . |
✔️ | ✔️ |
body | Required. The body of the request. | ❌ | ✔️ |
If properties are defined in both Attributes and RequestBody
, priority is given to data provided in RequestBody
.
See the Example section for complete examples.
Usage
To use the Dapr service invocation output binding, learn more about how to use Dapr service invocation in the official Dapr documentation.
To use the daprInvoke
in Python v2, set up your project with the correct dependencies.
In your
requirements.text
file, add the following line:azure-functions==1.18.0b3
In the terminal, install the Python library.
pip install -r .\requirements.txt
Modify your
local.setting.json
file with the following configuration:"PYTHON_ISOLATE_WORKER_DEPENDENCIES":1