Minimal web apis in .NET with Azure API Management

Minimal Web APIs in .NET and Azure API Management Combined

This article is my contribution for the Christmas holiday seasons for the yearly community knowledge sharing initiative of CloudFamily’s Festive Tech Calendar 2022, for December 14th. 

In this blog article, you will learn about Minimal Web APIs in .NET and how to implement and deploy it to Azure through Azure API Management.

NOTE: This is an inclusive blog post, which means, this is not an advanced level nor super beginner level neither.
Just enough to get everyone started on these technologies. 

Please feel free to toggle on the sub-topics in the table of contents. 

Table of Contents

FestiveTechCalendar is a community initiative that shares knowledge throughout the month of December as we bring you lots of new content from different communities and people around the globe.

Minimal Web APIs - The Basics and Origin

Before I start sharing my thoughts about minimal Web APIs, I would like to start with the concept of “Less is More.”
I assume you have heard of it, and probably some of you are applying the concepts of minimalism.

In the concepts of focus and work, the fewer distractions we have, the more focus we get. In relevance to this, as developers, although every problem can have unique way of solution, we try our best to write cleaner code regardless of the programming languages, frameworks, and tools we use. We have serverless technologies and tools that help us, with productivity and let us focus on what we suppose to do. 

Web APIs vs. REST APIs

REST API vs Web API

In the world of web development, there are several confusing words that we often hear and let them pass because we can’t wrap our heads around them. They include Web API, REST API, and SOAP API, among others. If you have been finding these words confusing, read through to understand what they mean, how they relate, and their differences.

Minimal APIs Idea Started in the Developer Community

Minimal Web API has the “minimal” in it due to this concept of minimalism in the code. Aside from its original history, in the world of .NET community, it also started as one of the features released when .NET 6 came. 

The Origin of Minimal APIs

The story of the minimal API started in November 2019. The developer community got a chance to see the implementation of the distributed calculator in Go, Python, C#, and Javascript. When the community started comparing how many files and lines of code are needed to do almost the same thing with C# compared to other languages, it was apparent that C# seems more complicated than the rest of them.

The Minimal Web APIs in .NET is designed to develop HTTP APIS with fewer dependencies. They are intended for specific use cases like applications requiring minimal dependencies, such as microservices. Furthermore, other issues when it needs to be lightweight, or perhaps you need a prototype of a solution. 

The Model-View-Controller Pattern (MVC)

Minimal APIs are considered lightweight and quicker than the web API that uses controllers. The APIs with controllers in .NET uses the typical MVC architectural design pattern.

When I was learning C# in .NET for the first time, the Model-View-Controller(MVC) pattern was the first design pattern I had to learn to build my applications or APIs. NET. Back then, it was .NET 4

In my own hand-sketched diagram below, MVC design patterns are used to split the application into interconnected elements to separate concerns and decouple application components. 

MVC Design pattern diagram hand-sketched by Jonah Andersson

Model is where you define your data structures, View is where your UI or display your business data to your users, Controller maps the requests and this is where you control the data that you prefer to pass on to the view. 

Minimal APIs - an alternative MVC Pattern without the Controllers in .NET

In contrary to the traditional MVC pattern, the minimal APIs in .NET do not use the typical MVC controllers we are used to writing as .NET developers. Because of the purpose of minimalism behind it.

As mentioned earlier, the minimal APIs have the intention and purpose of keeping our code simple and clean, with fewer files. This concept makes the development of API help in a way that we develop with compact syntaxes of code than the usual MVC pattern with controllers. 

Here are some of the known Features of Minimal APIs in .NET: 

  • Lightweight and faster compared to APIs with Controllers (MVC)
  • Customization and Control – It gives you better control of the structure of your APIs
    (NoteWatch out for complexity)
  • Route Handlers are usually in the form of methods that gets executed when the route has a match. These route handler methods have the flexibility of different types, like a static, instantiable, local function, or lambda expression.
  • Parameter Bindings that help in translating the web data requests to strongly typed parameters
  • Endpoint Filters that can support and help with logging management in our code 
  • Route Group Filters used for filtering capabilities of route groups 
  • Authentication features for security 
  • Unit Testing 
  • Open API (Swagger) support
Suppose you need to build HTTP APIs with minimum components and want flexibility and control over how you develop your web APIs. In that case, minimal APIs can be useful. 

In addition to its features specifically in .NET, it helps us by removing the blockers of routine structure, but gives us the flexibility to create minimalistic APIs .NET without using controllers. When you minimize the use of having the logical layer of controllers, it makes it faster to build and compile compared to MVC pattern way of building Web APIs. 

The minimal APIs are also supported by the latest versions of .NET Framework (.NET 6, .NET 7) and the newest version of C# such the C# 10 and C# 11. 

Does this mean that we should start using minimal APIs in .NET instead of the MVC pattern with controllers? 

The answer is no. 

The MVC framework has been solid and powerful for many years and it has great features that minimal APIs do not have. You can think of minimal APIs as an alternative if you prefer it and it suits the purpose of your project. The MVC framework with controllers is not being replaced by it. 

Minimal Web APIs might not be ideal for all scenarios, considering the performance, complexity, flexibility, etc., you want to achieve. 

As mentioned, every developer is unique and every problem or project is unique. Before hopping into creating projects with minimal APIs in .NET, take time to review your system or application architecture first, and check it fits the domain and purpose. 

Getting Started with Minimal Web APIs in C# .NET 6 or .NET 7

Technical Prerequisites

  • Basic knowledge of how APIs works 
  • A project plan or goal
  • Programming Language: C# 
  • Latest version of SDK of NET 6 or .NET 7 
  • Postman or any REST Client Tool
  • Code Editor: Visual Studio, VSCode or any supported IDE of your choice 

The Beginners Hello World in Minimal API

In the following code snippet, you can say hello to the world in a simple line of string and a few lines.  

				
					var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World! Thanks for reading Jonah's blog to learn about minimal web APIs in .NET!");
app.Run();
				
			

Minimal Web API Options and Features You Can Implement

In my .NET projects or development, I usually use Visual Studio 2022 or VS Code as my IDE.  When you start a project in Visual Studio, you would typical create the ASP.NET Core Web API project which is ideal for C# and cross platform development of Web APIs. 

Upon creating the ASP.NET Core Web API project, you will be asked for additional options like the type of Framework of .NET you prefer. In this example, in my demo project, there are currently two options. .NET 6 (LTS) and .NET 7 (STS).  If you are curious about the updated support for the different .NET Versions, check out Microsoft’s .NET Support Policy. 

Additionally, you can choose if you want to add authentication, like the Microsoft Identity Platform or Windows Authentication.

Aside from choosing the preferred authenticated type, you can also choose to enable Docker (based on support) and have additional options, OpenAPI support, which uses Swagger, and whether to use top-level statements. 

You wouldn’t need to uncheck the option to Use Controllers for minimal API development. 

Project and Code Structure in Minimal APIs in .NET

In my simple mini demo projects for this blog article, you will see that I have structured my code in different folders. I grouped my classes under EntityClasses, Components, and even have a group folder specific to my router classes under RouterClasses.

You may structure your folder depending on how you want to organize your code. In my project, you will see that I have Connected Service like the Azure API Management since I have deployed and published this API project to Azure through the service. 

As for Frameworks and Dependencies, I have a few in this simple project, as above. 

Project Structure of Minimal Web API

The Program.cs

				
					using DotNetMinimalAPIDemo.RouterClasses;
using DotNetMinimalAPIDemo.Components;

// Create builder and logging
var builder = WebApplication.CreateBuilder(args);
builder.Logging.ClearProviders();
builder.Logging.AddConsole();

// Add services to the container, CORS, and Swagger
// Learn more about Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddCors();

// Add "Router" classes as a service for each (Customer and Product, example only)
builder.Services.AddScoped<RouterBase, ProductRouter>();
builder.Services.AddScoped<RouterBase, CustomerRouter>();

var app = builder.Build();

//Use Cors need NuGet Package for it.
app.UseCors(x => x.AllowAnyHeader().AllowAnyMethod()
// If you want multi localhost port numbers,etc 
.WithOrigins("https://localhost:5296", "http://localhost:64714"));


// Configure the HTTP request pipeline 
// App environment you can customize here based on the different environments you want to set-up and add appropriate data 
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

//*************************************
// Add Routes from all "Router Classes" folder 
//*************************************
using (var scope = app.Services.CreateScope())
{
    // Instance of services where you build all RouterBase classes
    var services = scope.ServiceProvider.GetServices<RouterBase>();
    
    // Loop through each RouterBase class
    foreach (var item in services)
    {
        // Invoke the AddRoutes() method for each RouterBase class
        item.AddRoutes(app);
    }
    
    // Make sure this is called within the application scope
    app.Run();
}

				
			

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.

Content of RouterBase.cs

				
					namespace DotNetMinimalAPIDemo.Components
{
    public class RouterBase
    {
        public string? UrlFragment;
        protected ILogger? Logger;
        public virtual void AddRoutes(
        WebApplication app)
        {
        }
    }
}

				
			

Example of a Router Class = CustomerRouter.cs -> AddRoutes()

				
					 /// <summary>
        /// Method AddRoutes() calls the app.MapGet() method using the WebApplication app variable that has been initiated and passed in from the file Program.cs 
        ///  The MapGet() method has a first param of the route name the user sends the request to, such as http://
        /// localhost:portnr/product or http://localhost:portnr/customer
        
        //</summary>
        /// <param name="app">A WebApplication object</param>
        public override void AddRoutes(WebApplication app)
        {
            app.MapGet($"/{UrlFragment}", () => Get());

            app.MapGet($"/{UrlFragment}/{{id:int}}",
            (int id) => Get(id));

            app.MapGet($"/{UrlFragment}/{{name}}",
           (string name) => GetByFirstName(name));

            app.MapPost($"/{UrlFragment}",
            (Customer entity) => Post(entity));
            
            app.MapPut($"/{UrlFragment}/{{id:int}}",
            (int id, Customer entity) => Put(id, entity));

            app.MapDelete($"/{UrlFragment}/{{id:int}}",
            (int id) => Delete(id));
        }
    }
				
			

Below is a simple example of how you can get data by ID. For example, in this case, if I wanted to get the customer details by customer Id.

				
					 /// <summary>
        /// Gets a customer data by ID passed in as parameter
        /// </summary>
        /// <returns>An IResult object</returns>
        protected virtual IResult Get(int id)
        {
            // Get customer data by Id 
            Customer? current = GetAll()
            .Find(c => c.CustomerID == id);
            if (current != null)
            {
                return Results.Ok(current);
            }
            else
            {
                return Results.NotFound();
            }
        }
				
			

In the one of the router classes of the object CustomerRouter.cs for example, there is a AddRoutes() method that takes the WebApplication as a parameter. In the method itself, has the out outline of the different application mapping for the the different CRUD-operations like Get to get the data for the Customer. MapGet() is used for GET-operations.
Other operations like MapPut(), MapPost(), and MapDelete(), etc. for other operations. 

Azure API Management for Minimal Web APIs

In this minimal web API demo, I have I have used the Azure API Management service in Microsoft Azure.

To those who are new to Azure API Management, it is worth knowing that it is a Platform-as-a-Service(Paas) service in Azure that supports hybrid, multi-cloud API management in different platforms. One of the great features of this PaaS solution in Azure is that it supports the complete API lifecycle.

In 2022, Microsoft was named a Leader in 2022 Gartner® Magic Quadrant™ for Full Life Cycle API Management

So what does Azure API Management helps its users?

Azure API management helps abstract the backend architecture and its complexity from the consumers of the APIs. It also supports exposing your APIs (in Azure or external) without compromising the security of sharing them with the public consumers. 

In the above YouTube video, you will find a good use case of Vipps and how Azure API management helped the company in the success of its implementation.  

The illustration from Microsoft Documentation: What is Azure API Management, below describes the basic structure of how Azure API management works in the big picture. 

The API Management are composed of major components like shown in the middle of the illustration,  the Management Portal , Developer Portal and the API Gateways.  To the left, you will see the users of the API which are the Developers and Consumers/API users. To the right, you see an example on how it is integrated with other services in Azure and even with how it can be connected with external services using serverless solutions like Azure Functions. 

Image Credit: Microsoft Documentation

There is a lot to learn about Azure API management. I recommend checking out this e-book from Microsoft, Azure API and Microservices.  

There is also a great book “Mastering Azure API Management” by fellow Microsoft Azure MVP in Norway, Sven Malvik, that I personally have a copy. Sven is one of the presenter and speakers of the Vipps case study on the video of this blog article. 

Deploying Minimal Web APIs to Azure API Management

So after local development, you may test your APIs and its CRUD operations using OpenAPI (Swagger) or Postman, and then test deploy it to Azure API Management. 

Swagger UI for the APIs created with minimal APIs .NET 7
If I were to test run the GET method in getting all the customers that I developed through my CustomerRouter class, then you will get the HTTP 200 OK, and get the results of the data in JSON format.
This is how the minimal API .NET looks like after deploying to Azure API Management. In this section, you will see that the methods that I have created have been setup with the routing for products as an example.

Final Thoughts and Greetings

I hope that this article has been helpful to you, especially if you are new to Minimal Web APIs in .NET 6 or .NET 7. 

If you have any questions, feedback on content to add to this, or want a copy of my demo repo illustrated on this blog, please reach out to me via the social links below, or feel free to comment.

If you find this useful, please share your knowledge by sharing this article on LinkedIn or Twitter. Feel free to tag me or mention me.

Otherwise, I wish you a Merry Christmas in advance. Happy Holidays and Thank you for reading this contribution to the CloudFamily’s Festive Tech Calendar. 

Recommended Learning Resources

About Author:  Jonah Andersson is a Filipina-Swedish Senior Software Engineer who codes full-stack system development in C# .NET and works with DevOps and Cloud Infrastructure Engineering in Azure. 

She is a
Microsoft MVP for Azure, a Certified Azure Developer and DevOps Engineer,  Microsoft Certified Trainer, Public Speaker, and Tech Mentor.  She is also the author of the O’Reilly Media Book, “Learning Microsoft Azure: Cloud Computing and Development Fundamentals,” and the Founder & Community Leader of Azure User Group Sweden. 

Jonah is passionate about learning, developing, and sharing knowledge about Microsoft Azure cloud technologies. She is advocating gender equality and diversity in the tech industry through mentorship and by being a role model. She also loves creative technical writing and shares her experience. 

Connect and Follow Jonah Andersson

Share the knowledge

Leave a Comment

Your email address will not be published. Required fields are marked *