.NET 6 Minimal APIs vs Node JS
With the release of .NET 6 comes a new way to create APIs; a more concise, less verbose way.
Top Level Programs
In .NET 5 and C# 9 we were given a new concept called top level programs. Top level programs were designed to minimise the boilerplate code needed for getting an application up and running. For example, in .NET Core 3.1 running dotnet new console would produce this boilerplate code:
In contrast, running dotnet new console in .NET 5 would create this code.
As you can see in the second example, there is much less code. This makes your code easier to understand and doesn’t have the unnecessary boilerplate (namespaces, classes etc) around the main functionality, which in this case is just printing the string “Hello World!” To the console.
Global Usings and ImplicitUsings
In C# 10 a new language feature was added that allows us to declare a global using statement using the global keyword as shown below. This means we can declare all our using statements global to our application in one place. We can create a GlobalUsings.cs file and put all our declarations in here away from the .cs files that contain our application code.
The declared global usings will make the namespaces available throughout our application, without us having to create them in each and every .cs file.
In addition to this in .NET 6.0 there is a new project property called ImplicitUsings
This tells the framework to automatically generate a .cs file in our build folder that includes all the global usings needed for our application to work by using the global keyword described earlier.
Global usings and ImplicitUsings mean we can omit duplicated using statements from every .cs file and massively reduce the amount of boilerplate statements needed. These two new features along with top level programs described earlier enables minimal APIs to work.
Minimal APIs can be thought of as APIs without a controller. In the versions of .NET before 6.0, when you created a new web project you would get a project that looked like the following, with classes, namespaces, startup files etc.
The program.cs file would look like this:
You would have to create a controller class and put your HTTP methods inside this controller then tell your application to map these controllers in your middleware. The templates handled most of this for you, but the code is still there and you still need to understand what your code is doing.
Contrast that to .NET 6 were executing the following dotnet new command
dotnet new web -o “DotNetMinApi”
Gives you the following project
With a program.cs file that looks like this:
As you can see, the minimal API drastically reduces the amount of boilerplate code needed to get a basic web service up and running. There are no controllers, no middleware, no dependency injection, no namespaces and using statements.
The .NET team wanted a way for developers to be able to easily create minimal APIs without being weighed down with classes, dependency injection, namespaces, and large portions of the .NET SDK being imported.
This may be somewhat inspired by Node.js which has pretty much taken this tact since its inception.
As you can see from this code taken from the getting started page on the Node.js website. There are some similarities to what minimal APIs are trying to achieve in .NET 6.
In the above code there is no need to create classes, no need to inject dependencies into your IoC container and no need to pull in a large number of namespaces from the SDK to get a basic web service up and running.
In the modern world of microservice architecture and serverless computing where services are being more and more decoupled from each other, there is a need to spin up and create small services that serve very specific needs. I think minimal APIs help go some way to achieving that by reducing the friction of generating new .NET applications. It helps keep thing simple and easy to understand.
This video from Maria Naggaga (Senior Program Manager .NET as Microsoft) goes more into Microsoft’s thinking behind minimal APIs