Coder Social home page Coder Social logo

chegeapollo11 / dapr-azure-functions-extension Goto Github PK

View Code? Open in Web Editor NEW

This project forked from azure/azure-functions-dapr-extension

0.0 1.0 0.0 376 KB

Extension for interacting with Dapr APIs from an Azure Function

License: Apache License 2.0

Python 1.20% C# 98.80%

dapr-azure-functions-extension's Introduction

Azure Functions dapr extensions

Build and Test Gitter License: MIT

⚠️ This extension is currently in preview and not recommended for production. ⚠️

The Azure Functions Dapr extension allows you to easily interact with the Dapr APIs from an Azure Function using triggers and bindings. This extension is supported in any environment that supports running Dapr and Azure Functions - primarily self-hosted and Kubernetes modes.

If you are unfamiliar with Azure Functions, it's recommended to try out an Azure Function's quickstart first to understand the basics of the programming model.

You can also jump to the Dapr + Functions quickstart below.

This extension currently supports Azure Functions written in C#, JavaScript / TypeScript, and Python.

module.exports = async function (context, req) {
    context.log('Function triggered.  Reading Dapr state...');

    context.log('Current state of this function: ' + context.bindings.daprState);

    context.log('Using Dapr service invocation to trigger Function B');

    context.bindings.daprInvoke = {
        appId: 'function-b',
        methodName: 'process',
        httpVerb: 'post',
        body: context.bindings.daprState
    }

    context.res = {
        status: 200
    };
};

Function Triggers

Azure Function triggers start an execution.

Trigger Type Description Samples
daprBindingTrigger Trigger on a Dapr input binding C#, JavaScript, Python
daprServiceInvocationTrigger Trigger on a Dapr service invocation C#, JavaScript, Python
daprTopicTrigger Trigger on a Dapr topic subscription C#, JavaScript, Python

Function Bindings

Azure Function bindings allow you to pull data in or push data out as during an execution. Input Bindings pass in data at the beginning of an execution at the time of triggering. Output Bindings push data out once an execution has completed.

Binding Type Direction Description Samples
daprState Input Pull in Dapr state for an execution C#, JavaScript, Python
daprSecret Input Pull in Dapr secrets for an execution C#, JavaScript, Python
daprState Output Save a value to Dapr state C#, JavaScript, Python
daprInvoke Output Invoke another Dapr app C#, JavaScript, Python
daprPublish Output Publish a message to a Dapr topic C#, JavaScript, Python
daprBinding Output Send a value to a Dapr output binding C#, JavaScript, Python

Quickstart

You can run through a quickstart of developing some JavaScript Azure Functions that leverage Dapr with the following tutorial

Installing the extension

.NET Functions

Install the NuGet package for this extension into your function app project.

Non-.NET Functions

While this extension is in preview it is not included in the default extension bundle for functions. You can still include it, but will need to manually install it into the project, and opt-out to using the default extensions.

  1. Open the host.json file from the root of the project and remove the extensionBundle property and values (if they exist). Save the file.
  2. Run func extensions install -p Dapr.AzureFunctions.Extension -v 0.10.0-preview01. Be sure to use the latest version as published on NuGet. You must have the .NET Core SDK installed in order for this command to work.

This also means for other extensions your app may be leveraging (e.g. Azure Service Bus or Azure Storage) you will need to manually install them using the NuGet package for that extension. For example, with Azure Storage the documentation links to a NuGet package for that extension where you could include in your app with this Dapr extension by running func extensions install -p Microsoft.Azure.WebJobs.Extensions.Storage -v 4.0.2.

Developing the extension

The samples in this repo (other than the quickstart) are set up to run using a local build of the extension.

You can use a development build of the extension for any function by:

  • Referencing the Dapr.AzureFunctions.Extension project in your .NET function
  • Publishing the extension to the bin/ directory of your non-.NET function

Example for non-.NET function:

dotnet publish <path-to...>/Dapr.AzureFunctions.Extension -o bin/

Dapr ports and listeners

When you are triggering a function from Dapr, the extension will expose port 3001 automatically to listen to incoming requests from the Dapr sidecar.

IMPORTANT: Port 3001 will only be exposed and listened if a Dapr trigger is defined in the function app. When using Dapr the sidecar will wait to receive a response from the defined port before completing instantiation. This means it is important to NOT define the dapr.io/port annotation or --app-port unless you have a trigger. Doing so may lock your application from the Dapr sidecar. Port 3001 does not need to be exposed or defined if only using input and output bindings.

By default, when Azure Functions tries to communicate with Dapr it will call Dapr over the port resolved from the environment variable DAPR_HTTP_PORT. If that is null, it will default to port 3500.

You can override the Dapr address used by input and output bindings by setting the DaprAddress property in the function.json for the binding (or the attribute). By default it will use http://localhost:{DAPR_HTTP_PORT}.

The function app will still expose another port and endpoint for things like HTTP triggers (locally this defaults to 7071, in a container it defaults to 80).

Running and debugging an app

Normally when debugging an Azure Function you use the func command line tool to start up the function app process and trigger your code. When debugging or running an Azure Function that will leverage Dapr, you need to use dapr alongside func so both processes are running.

So when running a Dapr app locally using the default ports, you would leverage the dapr CLI to start the func CLI.

If no Dapr triggers are in the app

dapr run --app-id functionA --dapr-http-port 3501 -- func host start --no-build

If Dapr triggers are in the app

dapr run --app-id functionA --app-port 3001 --dapr-http-port 3501 -- func host start --no-build

Deploying to Kubernetes

You can annotate your function Kubernetes deployments to include the Dapr sidecar.

IMPORTANT: Port 3001 will only be exposed and listened if a Dapr trigger is defined in the function app. When using Dapr, the sidecar will wait to receive a response from the defined port before completing instantiation. This means it is important to NOT define the dapr.io/port annotation or --app-port unless you have a trigger. Doing so may lock your application from the Dapr sidecar. Port 3001 does not need to be exposed or defined if only using input and output bindings.

To generate a Dockerfile for your app if you don't already have one, you can run the following command in your function project: func init --docker-only.

The Azure Function core tools can automatically generate for you Kubernetes deployment files based on your local app. It's worth noting these manifests expect KEDA will be present to manage scaling, so if not using KEDA you may need to remove the ScaledObjects generated, or craft your own deployment YAML file. We do recommend including KEDA in any cluster that is running Azure Functions containers (with or without Dapr), but it is an optional component to assist with scaling.

An example of a function app deployment for Kubernetes can be found below.

The following command will generate a deploy.yaml file for your project: func kubernetes deploy --name {container-name} --registry {docker-registry} --dry-run > deploy.yaml

You can then edit the generated deploy.yaml to add the dapr annotations. You can also craft a deployment manually.

Azure Storage account requirements

While an Azure Storage account is required to run functions within Azure, it is NOT required for functions that run in Kubernetes or from a Docker container. The exception to that is functions that leverage a Timer trigger or Event Hub trigger. In those cases the storage account is used to coordinate leases for instances, so you will need to set an AzureWebJobsStorage connection string if using those triggers. You can set the AzureWebJobsStorage value to none if not using any of the triggers that require it.

Sample Kubernetes deployment

apiVersion: v1
kind: Service
metadata:
  name: my-function
  namespace: default
spec:
  selector:
    app: my-function
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-function
  namespace: default
  labels:
    app: my-function
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-function
  template:
    metadata:
      labels:
        app: my-function
      annotations:
        dapr.io/enabled: "true"
        dapr.io/id: "functionapp"
        # Only define port of Dapr triggers are included
        dapr.io/port: "3001"
    spec:
      containers:
      - name: my-function
        image: myregistry/my-function
        ports:
        # Port for HTTP triggered functions
        - containerPort: 80
---

dapr-azure-functions-extension's People

Contributors

wenhzha avatar amanbha avatar jeffhollan avatar cgillum avatar vinayada1 avatar rynowak avatar aaroncrawfis avatar mchmarny avatar greenie-msft avatar lcartel-ms avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.