Sarıkaya Dev Logo

Integrating .NET 8 Minimal APIs with Azure OpenAI Function Calling for Smart Chatbots

Mahmut Sarıkaya 4 min read 4 Views 0
Integrating .NET 8 Minimal APIs with Azure OpenAI Function Calling for Smart Chatbots

Why combine Minimal APIs and Azure OpenAI?

Imagine a chatbot that can not only answer questions but also trigger real‑world actions such as booking a meeting or fetching the latest weather. Since the release of .NET 8, Minimal APIs let developers expose HTTP endpoints with just a few lines of code, while Azure OpenAI’s function calling feature turns language models into orchestrators for external services. Marrying these two technologies reduces boilerplate, shortens time‑to‑market, and keeps the entire stack inside the familiar C# ecosystem.

Setting up the .NET 8 project

Start with the .NET 8 SDK (released November 2023) on Windows, macOS, or Linux. Create a new web project that targets the minimal‑API template:

dotnet new web -n ChatbotApi --framework net8.0

Navigate into the folder and restore packages. The default project already includes Microsoft.AspNetCore.App, which provides the routing and dependency‑injection infrastructure you need.

Adding Azure OpenAI client

Install the official Azure AI SDK. It bundles the OpenAIClient class that knows how to talk to the Azure OpenAI endpoint.

dotnet add package Azure.AI.OpenAI

In Program.cs, register the client as a singleton. Replace YOUR_RESOURCE and YOUR_KEY with the values from the Azure portal.

using Azure.AI.OpenAI; using Azure; var builder = WebApplication.CreateBuilder(args); builder.Services.AddSingleton(new OpenAIClient(new Uri("https://YOUR_RESOURCE.openai.azure.com/"), new AzureKeyCredential("YOUR_KEY"))); var app = builder.Build();

Defining function calls for the chatbot

Function calling works by describing a JSON schema that the model can invoke. For a weather‑lookup scenario, define a function named GetWeather with a single city parameter.

var weatherFunction = new FunctionDefinition( name: "GetWeather", description: "Returns current weather for a given city.", parameters: new Dictionary<string, FunctionParameter> { { "city", new FunctionParameter(type: "string", description: "Name of the city") } } );

When constructing ChatCompletionsOptions, add the function definition and set FunctionCall = "auto". The model will decide whether to call the function based on the user’s request.

Full Minimal API example

The following snippet shows a complete endpoint that receives a user message, forwards it to Azure OpenAI, and, if a function call is returned, executes a mock weather service before responding.

app.MapPost("/chat", async (ChatRequest request, OpenAIClient client) => { var messages = new List<ChatMessage> { new ChatMessage(ChatRole.System, "You are a helpful assistant."), new ChatMessage(ChatRole.User, request.Message) }; var options = new ChatCompletionsOptions(messages) { Functions = { weatherFunction }, FunctionCall = "auto" }; var response = await client.GetChatCompletionsAsync("gpt-4o-mini", options); var choice = response.Value.Choices.First(); if (choice.FinishReason == CompletionsFinishReason.FunctionCall) { var functionCall = choice.Message.FunctionCall; var city = functionCall.Arguments["city"].ToString(); var weather = $"Sunny, 24°C in {city}"; var followUp = new ChatMessage(ChatRole.Assistant, $"Function GetWeather returned: {weather}"); messages.Add(choice.Message); messages.Add(followUp); var finalResponse = await client.GetChatCompletionsAsync("gpt-4o-mini", new ChatCompletionsOptions(messages)); return Results.Ok(new { reply = finalResponse.Value.Choices.First().Message.Content }); } return Results.Ok(new { reply = choice.Message.Content }); }); app.Run();

Notice how the code stays under 60 lines, yet it covers request parsing, function definition, conditional execution, and final response composition—all within the Minimal API paradigm.

Testing the endpoint

Run the application with dotnet run. Use curl or a tool like Postman to send a JSON payload:

curl -X POST http://localhost:5080/chat -H "Content-Type: application/json" -d '{"Message":"What's the weather in Berlin?"}'

The response will contain the weather string if the model invoked GetWeather. Inspect the finish_reason field in the raw OpenAI response to verify that function calling occurred.

Performance tips for production

1. Enable HTTP/2 on the Kestrel server to reduce latency when calling Azure OpenAI.
2. Cache frequent function results (e.g., city weather) using MemoryCache with a 5‑minute expiration to avoid unnecessary API calls.
3. Set max_tokens and temperature explicitly in ChatCompletionsOptions to keep costs predictable; a typical chatbot uses 150‑200 tokens per turn and a temperature of 0.7.
4. Deploy to Azure App Service or Azure Container Apps with the “Always On” setting, ensuring the minimal API stays warm during peak traffic.

Sources

  • Microsoft Docs – Azure OpenAI Service
  • dotnet.microsoft.com – .NET 8 Minimal APIs guide
  • OpenAI API reference – Function calling

Author: Mahmut Sarıkaya — sarikayadev.com

Tags: #dotnet 8 #minimal APIs #azure openai #function calling #chatbot development
Share:
M

Written by

Mahmut Sarıkaya

Software Developer

Comments

No comments yet. Be the first to share your thoughts!

Leave a Comment

2 + 7 =