FunctionsFramework.Generator 0.2.4

There is a newer version of this package available.
See the version list below for details.
dotnet add package FunctionsFramework.Generator --version 0.2.4
                    
NuGet\Install-Package FunctionsFramework.Generator -Version 0.2.4
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="FunctionsFramework.Generator" Version="0.2.4" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="FunctionsFramework.Generator" Version="0.2.4" />
                    
Directory.Packages.props
<PackageReference Include="FunctionsFramework.Generator" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add FunctionsFramework.Generator --version 0.2.4
                    
#r "nuget: FunctionsFramework.Generator, 0.2.4"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package FunctionsFramework.Generator@0.2.4
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=FunctionsFramework.Generator&version=0.2.4
                    
Install as a Cake Addin
#tool nuget:?package=FunctionsFramework.Generator&version=0.2.4
                    
Install as a Cake Tool

FunctionsFramework

Define HTTP handlers once and generate ASP.NET Core Minimal APIs, AWS Lambda Annotations functions, Azure Functions, a typed C# HTTP client, and OpenAPI from the same declarations. The framework is standalone. Its runtime and examples target .NET 10; the Roslyn generator targets .NET Standard 2.0.

NuGet packages

Each push to main builds, tests, and publishes FunctionsFramework, FunctionsFramework.AwsLambda, and FunctionsFramework.Generator to NuGet.org. GitVersion computes a unique version for each main-branch commit: Conventional Commits feat: bump the minor version, fix: and perf: bump the patch, and a ! or BREAKING CHANGE: footer bumps the major. Other commits bump the patch. +semver: skip and +semver: none are rejected on main so they cannot reuse a published version. No release tags are required. CI also builds and tests pull requests. Publishing uses NuGet.org trusted publishing through GitHub Actions OIDC; no stored API key is required. Set the repository Actions variable NUGET_USER to the NuGet.org username associated with the trusted publishing policy. The policy must authorize this repository and publish.yml with no GitHub environment specified.

The packages are available from the standard NuGet.org source. The generator package includes the analyzer and both adapter targets, but does not import them automatically: a producer and each host must select the appropriate targets explicitly. Use the published packages in application projects; no FunctionsFramework source checkout is needed. For example, add the generator package and producer target import:

<ItemGroup>
  <PackageReference Include="FunctionsFramework.Generator" Version="1.2.3"
                    GeneratePathProperty="true" PrivateAssets="all" />
</ItemGroup>
<Import Project="$(PkgFunctionsFramework_Generator)/tools/FunctionAdapterProducer.targets" />

In a host, use the same package reference and import $(PkgFunctionsFramework_Generator)/tools/FunctionAdapters.targets. The functions library can reference FunctionsFramework; AWS hosts can also reference FunctionsFramework.AwsLambda. Keep all package versions aligned.

Contents

Path Purpose
src/FunctionsFramework HTTP attributes, parameter binding attributes, results, and typed result unions; no hosting dependencies
src/FunctionsFramework.Generator Incremental generator, embedded result converters, client generation, OpenAPI, and diagnostics
src/FunctionsFramework.AwsLambda Shared Lambda bootstrap and generated SAM HTTP API template reader
src/FunctionsFramework.OpenApiClientGenerator OpenAPI-based standalone browser client, DTO, interface, and JSON context generator
build/FunctionAdapterProducer.targets Generates the complete adapter set in a separate compilation
build/FunctionAdapters.targets Compiles the selected adapter into a host and exports openapi.json
samples One functions project, a producer, all three hosts, and a client
tests/FunctionsFramework.Tests Framework regression tests independent of any application

Try the example

From this directory:

dotnet build FunctionsFramework.slnx '-bl:/tmp/functions-build-{}.binlog'
dotnet test tests/FunctionsFramework.Tests/FunctionsFramework.Tests.csproj '-bl:/tmp/functions-tests-{}.binlog'
dotnet run --project samples/Example.MinimalApi -- --urls http://localhost:5187

GET /greetings/Ada?title=Dr returns a typed JSON greeting. POST /greetings accepts {"name":"Ada"} and returns HTTP 201 with a Location header; an empty name returns HTTP 400. Set ASPNETCORE_ENVIRONMENT=Development to serve the Minimal API's generated document at /openapi/v1.json.

The Azure and AWS sample projects compile the same handlers using their own SDKs. Azure local execution additionally requires Functions Core Tools and host storage configuration. AWS deployment uses the generated serverless.template. Building these samples does not deploy resources.

Add functions to an application

In the application's functions class library, reference the published FunctionsFramework package:

<ItemGroup>
  <PackageReference Include="FunctionsFramework" Version="1.2.3" />
</ItemGroup>

Use using FunctionsFramework; in handlers:

using FunctionsFramework;

namespace MyApplication.Functions;

public sealed record Greeting(string Message);

public sealed class GreetHandler
{
    [HttpFunction("greetings/{name}", FunctionHttpMethod.Get, Name = "Greet")]
    public OkFunctionResult<Greeting> Handle(string name)
        => FunctionResults.Ok(new Greeting($"Hello, {name}!"));
}

Register application services in each host. The generated AddGeneratedFunctionHandlers() registers the instance handlers as scoped services. Handlers can depend on application interfaces through their constructors.

Create a separate producer class library next to the functions project:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <Nullable>enable</Nullable>
    <FunctionGeneratedNamespace>MyApplication.Generated</FunctionGeneratedNamespace>
    <FunctionApiClientNamespace>MyApplication.ApiClient</FunctionApiClientNamespace>
    <FunctionOpenApiTitle>My Application API</FunctionOpenApiTitle>
  </PropertyGroup>
  <ItemGroup>
    <ProjectReference Include="../Functions/Functions.csproj" />
    <PackageReference Include="FunctionsFramework.Generator" Version="1.2.3"
                      GeneratePathProperty="true" PrivateAssets="all" />
  </ItemGroup>
  <Import Project="$(PkgFunctionsFramework_Generator)/tools/FunctionAdapterProducer.targets" />
</Project>

The three settings are optional. Defaults are FunctionsFramework.Generated, FunctionsFramework.ApiClient, and HTTP API. Set them in the producer; every consuming host receives the same generated contract. Multiple applications can choose distinct client namespaces.

Each host or client references the functions project, selects an adapter, and imports the consumer targets:

<PropertyGroup>
  <FunctionAdapterHost>MinimalApi</FunctionAdapterHost>
  <FunctionAdapterProducerProject>../Functions.Generated/Functions.Generated.csproj</FunctionAdapterProducerProject>
</PropertyGroup>
<ItemGroup>
  <ProjectReference Include="../Functions/Functions.csproj" />
  <PackageReference Include="FunctionsFramework.Generator" Version="1.2.3"
                    GeneratePathProperty="true" PrivateAssets="all" />
</ItemGroup>
<Import Project="$(PkgFunctionsFramework_Generator)/tools/FunctionAdapters.targets" />

Supported hosts are MinimalApi, Aws, Azure, and ApiClient. Use the sample projects for the corresponding SDK and package references. Azure's SDK version also appears in global.json so generated extension projects can resolve it.

In Minimal API startup, import your configured generated namespace and call:

builder.Services.AddGeneratedFunctionHandlers();
var app = builder.Build();
app.MapGeneratedFunctions();
app.Run();

Azure and AWS call AddGeneratedFunctionHandlers() in their normal startup code. AWS additionally needs a LambdaStartup, a serializer assembly attribute, and a serverless.template; these are shown in samples/Example.AwsLambda.

The separate producer is necessary because source generators cannot consume each other's output in the same compilation. The targets copy generated source beneath each host's intermediate directory so Azure and AWS's SDK generators can discover entry points and deployment metadata. Generated files are tracked for cleaning; design-time builds do not rewrite the adapters or AWS deployment template.

Handler contracts

Routes support literal segments and {parameter} segments. Route constraints, optional segments, catch-alls, duplicate placeholders, and reserved parameter names are rejected. Supported verbs are Get, Post, Put, Patch, Delete, Head, and Options. Names default to the class name with Handler removed; explicitly set Name to keep generated operation and client names stable across class renames.

Parameters matching a placeholder bind from the route. Other scalar parameters bind from the query string. [FromFunctionRoute(Name = "id")] and [FromFunctionQuery(Name = "limit")] override binding names. Scalars include strings, booleans, characters, numbers, enums, Guid, DateTime, DateTimeOffset, DateOnly, and TimeOnly. Parsing uses invariant culture and respects nullable query parameters and defaults. Missing or invalid inputs return HTTP 400.

Use [FromFunctionBody] for one JSON body. A CancellationToken receives request cancellation (or Lambda's remaining execution time). Public non-generic handlers may return FunctionResult subtypes, Task<T>, or ValueTask<T>; static methods are also supported.

FunctionResults provides Ok, Created, Accepted, NoContent, BadRequest, NotFound, Conflict, Unauthorized, Forbid, StatusCode, Json, Text, and File factories. FunctionResults<T1, T2> supports two to four alternatives with implicit conversion. Declare typed payload results, such as OkFunctionResult<Greeting>, so the client and OpenAPI generator can discover the response DTO. Untyped results remain available when the response cannot be described statically.

Object bodies use JSON, including JSON string quoting. Json(null) writes JSON null. Created results set Location; Unauthorized and Forbid return bare 401/403 responses. Hosts own authentication and authorization configuration.

Hosts dispose returned file streams after writing them. ASP.NET Core and Azure stream directly. AWS buffers binary output into a base64 API Gateway response and remains subject to AWS payload limits. File results can enable single-byte-range and suffix-range requests, including HTTP 206 and 416 responses.

Typed client and OpenAPI

The ApiClient adapter emits IApiClient, ApiClient, and per-operation response families. Each <Operation>Async method accepts typed route/query/body parameters and an optional cancellation token. Dispose the response after use:

using FunctionsFramework.ApiClient; // Or your configured namespace.

using var http = new HttpClient { BaseAddress = new Uri("http://localhost:5187/") };
IApiClient client = new ApiClient(http);
using var response = await client.GreetAsync("Ada");
if (response is GreetResponse.Ok(var greeting))
    Console.WriteLine(greeting.Message);

The caller owns HttpClient. Configure its base address as the API root, including Azure's /api/ or an API Gateway stage prefix when applicable. Optional null query values are omitted and path/query values are escaped. Undeclared responses use an Unexpected case; malformed required JSON throws JsonException. File responses keep their content stream open until disposed and support an optional range header.

Each consumer receives FunctionOpenApi.Document in the generated namespace and an openapi.json in its build/publish output. The OpenAPI 3.0.3 contract includes operation names, bindings, request bodies, and typed response schemas. Azure and AWS expose a generated GET openapi/v1.json endpoint unless a handler already owns that route. Azure applies the same function authorization as its other endpoints. Minimal API hosts choose when to map the document, as demonstrated in the sample.

Standalone browser client generator

When a browser client should use its own DTOs rather than reference the server's functions assembly, generate a standalone client from the exported OpenAPI file:

dotnet run --project src/FunctionsFramework.OpenApiClientGenerator -- \
  --openapi samples/Example.MinimalApi/bin/Debug/net10.0/openapi.json \
  --contracts-dir /tmp/example-client \
  --namespace Example.Client.Api \
  --client-name ExampleApiClient \
  --json-context-name ExampleJsonContext

The generator also exposes OpenApiClientGenerator.Generate(options) in the FunctionsFramework.OpenApiClientGeneration namespace for application-specific commands. --client-path overrides the client file location; --route-prefix optionally removes a leading API prefix from operation paths. No prefix is removed by default.

This generator retains its existing OpenAPI subset: object DTO schemas and JSON response families. Binary success bodies are consumed directly by browser URLs; use the Roslyn-generated ApiClient adapter for typed streaming responses.

Lambda local hosting

Reference src/FunctionsFramework.AwsLambda from a shared executable runner and from orchestration code that reads the generated template:

await FunctionsFramework.AwsLambda.LambdaRunner.RunAsync();

Set FUNCTIONS_FRAMEWORK_LAMBDA_HANDLER to the generated handler entry point, or pass it directly to RunAsync(handler). The executable also references the application's Lambda project so its handlers are present at runtime. LambdaHttpApiTemplate.Read(path) returns each HTTP function's logical ID, handler, and method/path routes. The application controls resource names, database references, environment configuration, and publishing.

Diagnostics: FF001 invalid handler signature; FF002 invalid routing metadata; FF003 invalid parameter binding; FF004 duplicate endpoint/name; FF005 invalid configured namespace.

There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.3.0 90 10/31/2026
0.2.4 91 10/31/2026