This project is no longer being actively maintained by the original author.
Forks or derivative works are encouraged!
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.
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.
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.
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.
Install the Azure Functions for Rust SDK using cargo install:
cargo install azure-functions-sdkThis installs a new cargo command named func that can be used to create and run new Azure Functions applications.
Use the cargo func new-app command to create a new Azure Functions application:
cargo func new-app helloThis will create a new application in the ./hello directory with a module named functions where the exported Azure Functions are expected to be placed.
Use the cargo func new command to create a new HTTP-triggered Azure Function named hello:
cargo func new http -n helloThe source for the function will be in src/functions/hello.rs.
To build your Azure Functions application, just use cargo build:
cargo buildIf 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 unstableThis enables Azure Functions for Rust to emit diagnostic messages that will include the position of an error within an attribute.
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 buildTo build and run your Azure Functions application, use cargo func run:
cargo func runIf you need to enable the unstable feature, pass the --features option to cargo:
cargo func run -- --features unstableThe 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.
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.
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_NAMECreate 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 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.
Azure Functions for Rust automatically infers the direction of bindings depending on how the binding is used in a function's declaration.
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
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.
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>:
CosmosDbDocumentEventHubMessageQueueMessageSendGridMessageServiceBusMessageSignalRGroupActionSignalRMessageTwilioSmsMessage
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.
Thanks goes to these wonderful people (emoji key):
This project follows the all-contributors specification. Contributions of any kind welcome!