Notice
This project is no longer being actively maintained by the original author.
Forks or derivative works are encouraged!
Azure Functions for Rust
A framework for implementing Azure Functions in Rust.
๐ฉ Disclaimer
This project is not an officially recognized Microsoft product and is not an endorsement of any future product offering from Microsoft.Microsoft and Azure are registered trademarks of Microsoft Corporation.
If you would like the Azure Functions team to consider supporting Rust, please vote up this feedback item.
Example
A simple HTTP-triggered Azure Function:
use azure_functions::{
bindings::{HttpRequest, HttpResponse},
func,
};
#[func]
pub fn greet(req: HttpRequest) -> HttpResponse {
format!(
"Hello from Rust, {}!\n",
req.query_params().get("name").map_or("stranger", |x| x)
)
.into()
}
Azure Functions for Rust also supports async functions:
use azure_functions::{
bindings::{HttpRequest, HttpResponse},
func,
};
use futures::future::ready;
#[func]
pub async fn greet_async(req: HttpRequest) -> HttpResponse {
// Use ready().await to simply demonstrate the async/await feature
ready(format!(
"Hello from Rust, {}!\n",
req.query_params().get("name").map_or("stranger", |x| x)
))
.await
.into()
}
See Building an async Azure Functions application for more information.
Get Started
Table of Contents
Installation
Requirements
.NET Core SDK
A .NET Core SDK is required to synchronize Azure Functions Host binding extensions.
For example, using the Cosmos DB bindings will need the Microsoft.Azure.WebJobs.Extensions.CosmosDB
extensions installed for the Azure Functions Host.
This happens automatically by Azure Functions for Rust when the application is initialized.
Follow the download instructions for the 2.2 .NET Core SDK to install for Windows, macOS, or your Linux distro.
Azure Functions Core Tools
Install version 2 or higher of the Azure Functions Core Tools.
If you are on Windows, you must add %ProgramFiles%\nodejs\node_modules\azure-functions-core-tools\bin
(where func.exe
is located) to the PATH
environment variable.
Installing the Azure Functions for Rust SDK
Install the Azure Functions for Rust SDK using cargo install
:
cargo install azure-functions-sdk
This installs a new cargo command named func
that can be used to create and run new Azure Functions applications.
Creating a new Azure Functions application
Use the cargo func new-app
command to create a new Azure Functions application:
cargo func new-app hello
This will create a new application in the ./hello
directory with a module named functions
where the exported Azure Functions are expected to be placed.
Adding a simple HTTP-triggered application
Use the cargo func new
command to create a new HTTP-triggered Azure Function named hello
:
cargo func new http -n hello
The source for the function will be in src/functions/hello.rs
.
Building the Azure Functions application
To build your Azure Functions application, just use cargo build
:
cargo build
If you are using a nightly compiler, you can enable improved error messages during compilation.
Add the following to your Cargo.toml
:
[features]
unstable = ["azure-functions/unstable"]
Build your application:
cargo build --features unstable
This enables Azure Functions for Rust to emit diagnostic messages that will include the position of an error within an attribute.
Building an async Azure Functions application
To build with support for async Azure Functions, add the following to your Cargo.toml
:
[dependencies]
futures-preview = "0.3.0-alpha.19"
And then build:
cargo build
Running the Azure Functions application
To build and run your Azure Functions application, use cargo func run
:
cargo func run
If you need to enable the unstable
feature, pass the --features
option to cargo:
cargo func run -- --features unstable
The cargo func run
command builds and runs your application locally using the Azure Function Host that was
installed by the Azure Functions Core Tools.
By default, the host will be configured to listen on 0.0.0.0:8080
.
For the hello
function added previously, it can be invoked from http://localhost:8080/api/hello
.
Debugging the Azure Functions application
The easiest way to debug the Azure Functions application is to use Visual Studio Code with the CodeLLDB extension.
By default, the Azure Functions for Rust SDK will create a Visual Studio Code launch configuration when you run cargo func new-app
.
This will enable a Debug
launch configuration that will build and run your application locally before attaching the lldb
debugger to the Rust worker process.
Deploying the Azure Functions application
In the future, there will be a cargo func deploy
command to deploy the Azure Functions application directly to Azure.
Until that time, you must manually build and push the Docker image to a repository that can be accessed by Azure.
Note: this requires Docker that is at least 18.06 for the experimental BuildKit support.
To enable the BuildKit support, set the DOCKER_BUILDKIT
environment variable to 1
before running docker build
.
Start by building your image with docker build -t $TAG_NAME .
:
docker build -t $TAG_NAME .
Where $TAG_NAME
is the tag name to use (e.g. username/my-functions-app
).
Use docker push
to push the image to a repository that is accessible to Azure Functions.
docker push $TAG_NAME
Create the "Function App (Classic)" in Azure using the "Linux (Preview)" OS. Under the "Publish" setting, select "Docker Image".
From the "Configure Container" section, select the repository and enter the image you pushed.
That's it! Once the Functions App starts in Azure, you should be able to view the functions and run them.
Azure Functions Bindings
Azure Functions supports a wide variety of input and output bindings that can be used by a function.
In a language like C#, parameters can be annotated with attributes describing how the parameters are bound.
Rust does not support attributes on parameters, so the #[binding]
attribute is applied on the function with a name that matches the parameter's identifier. The arguments to the attribute depend on the binding type.
The #[func]
attribute is used to turn an ordinary Rust function into an Azure Function. It works by examining the parameters and return type to the function and automatically mapping them to corresponding bindings.
The current list of supported bindings:
Rust Type | Azure Functions Binding | Direction | Vec<T> |
---|---|---|---|
Blob | Input and Ouput Blob | in, inout, out | No |
BlobTrigger | Blob Trigger | in, inout | No |
CosmosDbDocument | Input and Output Cosmos DB Document | in, out | Yes |
CosmosDbTrigger | Cosmos DB Trigger | in | No |
DurableActivityContext | Durable Activity Trigger | in | No |
DurableOrchestrationClient | Durable Orchestration Client | in | No |
DurableOrchestrationContext | Durable Orchestration Trigger | in | No |
EventGridEvent | Event Grid Trigger | in | No |
EventHubMessage | Event Hub Output Message | out | Yes |
EventHubTrigger | Event Hub Trigger | in | No |
GenericInput | Generic Input | in | No |
GenericOutput | Generic Output | out | No |
GenericTrigger | Generic Trigger | in | No |
HttpRequest | HTTP Trigger | in | No |
HttpResponse | Output HTTP Response | out | No |
QueueMessage | Output Queue Message | out | Yes |
QueueTrigger | Queue Trigger | in | No |
SendGridMessage | SendGrid Email Message | out | Yes |
ServiceBusMessage | Service Bus Output Message | out | Yes |
ServiceBusTrigger | Service Bus Trigger | in | No |
SignalRConnectionInfo | SignalR Connection Info | in | No |
SignalRGroupAction | SignalR Group Action | out | Yes |
SignalRMessage | SignalR Message | out | Yes |
Table | Input and Ouput Table | in, out | No |
TimerInfo | Timer Trigger | in | No |
TwilioSmsMessage | Twilio SMS Message Output | out | Yes |
More bindings will be implemented in the future, including support for retreiving data from custom bindings.
Bindings in Rust
Azure Functions for Rust automatically infers the direction of bindings depending on how the binding is used in a function's declaration.
Input bindings
Parameters of type T
or &T
, where T
is a trigger or input binding type, are inferred to be bindings with an in
direction.
#[func]
...
pub fn example(..., blob: Blob) {
...
}
#[func]
...
pub fn example(..., blob: &Blob) {
...
}
Additionally, some input binding types support parameters of type Vec<T>
and &Vec<T>
where T
is an input binding type:
#[func]
...
pub fn example(..., documents: Vec<CosmosDbDocument>) {
...
}
The following input bindings support parameters of type Vec<T>
:
CosmosDbDocument
Input-output (inout) bindings
Parameters of type &mut T
, where T
is a trigger or input binding type that supports the inout
direction, are inferred to be bindings with an inout
direction.
#[func]
...
pub fn example(..., blob: &mut Blob) {
...
}
Note: inout
direction bindings are currently not implemented for languages other than C#.
See this issue regarding this problem with the Azure Functions Host.
Output bindings
Functions that return a type T
, where T
is an output binding type, or a tuple of output binding types, are inferred to be bindings with an out
direction.
#[func]
...
pub fn example(...) -> Blob {
...
}
Functions may also return Option<T>
for any output binding type T
; a None
value will skip outputting a value.
#[func]
...
pub fn example(...) -> Option<Blob> {
...
}
#[func]
...
pub fn example(...) -> (HttpResponse, Option<Blob>) {
...
}
Additionally, some output binding types support returning Vec<T>
where T
is an output binding type:
#[func]
...
pub fn example(...) -> Vec<CosmosDbDocument>) {
...
}
The following output bindings support returning type Vec<T>
:
CosmosDbDocument
EventHubMessage
QueueMessage
SendGridMessage
ServiceBusMessage
SignalRGroupAction
SignalRMessage
TwilioSmsMessage
For functions that return a single output binding type, the binding has a special name of $return
and is treated as the return value of the function.
For functions that return a tuple of output binding types, the first value of the tuple has the binding name
of $return
and is treated as the return value of the function. The remaining values have binding names output1
, output2
, ..., output(N-1)
where N
is the number of types in the tuple, and are
treated as output bindings only.
Unit tuples ()
can be used in a tuple to "skip" a binding:
#[func]
...
pub fn example(...) -> ((), Blob) {
...
}
For the above example, there is no $return
binding and the Azure Function "returns" no value. Instead, a single output binding named output1
is used.
Contributors
Thanks goes to these wonderful people (emoji key):
This project follows the all-contributors specification. Contributions of any kind welcome!