0

Web API Updates with .NET 8

 1 year ago
source link: https://csharp.christiannagel.com/2023/04/19/api-dotnet8/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Preview 3 of .NET 8 includes a new project templates to create an API with a TODO service instead of the weather forecast . Looking into the generated code of this template, there are a lot more changes going on such as a slim builder and using a JSON source generator which helps when using AOT to create native .NET binaries. This article looks into the changes coming.

Planets and light

Todo service instead of weather forecasts

Besides dotnet new webapi which still creates a weather forecast service, a new template is available to create a Todo service. This template is named ASP.NET Core API (the other one is the template ASP.NET Core Web API) and is used with dotnet new api.

There are some interesting parts within this generated code. Let’s start with the simple parts. The first code snippet just shows the implementation of the Todo class. There’s nothing special other than using the DateOnly type which is already available since .NET 6.

TODO Class

In the same Todo.cs file, theres a TodoGeneratorclass which is used to generate some sample data. ThisTodoGeneratorcontains a field named_partswhich is an array consisting of three items. Everyone of this item is a tuple which consists of two arrays,PrefixesandSuffixes`. With .NET, more and more tuples are used, and this is a great use case for them.

Tuples to specify sample data

The method GenerateTodos creates random combinations combining the prefixes and suffixes from the parts, such as Walk the goat, Do the laundry, and Clean the car.

To do this, the variable titleMap is used which is another array of tuples combining three values: Row, Prefix, and Suffix. Using three for loops, the titleMap array is filled with all the possible combinations for the row (we have three rows with the three _parts values, the prefix (the sample code has one or two elements depending on the row), and the suffix which can only be used together with the prefix of a row. After the three iterations are completed, the titleMap array contains 16 items with values such as (0, 0, 0), (0, 0, 1), (0, 0, 2), up to `(2, 0, 3)’.

Next with Random.Shared.Shuffle, a new .NET 8 API is used to shuffle the titleMap array. This shuffles the array in place, and the result is a random order of the titleMap array. The titleMap array is then used to create the Todo objects with the first items of this array using the yield statement.

GenerateTodos

Slim Builder

Now let’s get into the really interesting parts. The Program.cs file contains the WebApplication and WebApplicationBuilder as we are used to. However, instead of invoking CreateBuilder, the new method CreateSlimBuilder is used. As the name suggests, this creates a builder which is slim, and it only contains a minimal set of features. The CreateSlimBuilder method is available with .NET 8.

What’s the difference between the CreateBuilder and the CreateSlimBuilder? Using .NET 8 preview 3, the CreateBuilder method registers 93 services in the dependency injection container. With the CreateSlimBuilder, 65 services are registered. Probably there’s some more change coming, but this is only a part of the story. Let’s get into the configuration and logging parts.

CreateSlimBuilder

Configuration Providers

The slim builder adds configuration providers to retrieve configuration from memory (MemoryConfigurationSource), and environment variables (EnvironmentVariablesConfigurationSource). Reading configuration from JSON files is no longer included by default.

Indeed, now there are multiple memory configuration sources and environment variables configuration sources while previously only one memory and environment variables configuration source was added. The different sources use different prefixes for configuration keys.

Do you use appsettings.json and appsettings.{environment}.json in your environment? Likely it depends on the hosting you use. If the application is running in a container, environmental variables might be all needed. Maybe you configure the settings with the service Azure App Configuration. In this case, you need to add this as a provider in any case. If you use JSON files, these configuration providers can easily be added to the builder.

Logging Providers

The method CreateBuilder adds four logger providers on the Windows platform: ConsoleLoggerProvider, DebugLoggerProvider, EventLogLoggerProvider, and EventSourceLoggerProvider. Using CreateSlimBuilder, doesn’t add any logging provider. Just the template generated code adds the ConsoleLoggerProvider to the logging builder. Just replace this line if you need another logging provider instead.

JSON Serializer Source Generator

If AOT is enabled when using the project template (using the command-line option --publish-native-aot), or by selecting the option Enable native AOT publish in Visual Studio, the JSON serializer source generator is used. This source generator is available since .NET 7, and it’s used to generate the serialization code for the Todo class.

Creating binary AOT code we need to try to get rid of reflecting code during runtime. For serializing .NET objects, the serializer uses reflection to get the properties of the object. You can use attributes to change the serializing behaviors. Using the runtime to analyze this information takes performance, and the trimming functionaly of the compiler is limited to not remove the code that’s needed during runtime. To solve this, source generators can be used to create this code during compile time how the serializer should behave.

For JSON serialization, the source code generator is available since .NET 7. The generated template contains this JsonSerializerContext derived partial class which has the attribute JsonSerializable attribute applied referencing the Todo array. With this, the compiler fills in the implemenation of the AppJsonSerializerContext class with compiler-generated code.

JSON Serialization Context

You can read the generated code with the Depencencies in Solution Explorer, open Analyzers, and select System.Text.Json.SourceGeneration. There you can see multiple source code files representing different features of the AppJsonSerializerContext for serialization.

The JSON context for the source generator is configured using the API ConfigureHttpJsonOptions. With this configuration, the source generated code is used on returningt the Todo objects.

Configuration of the JSON context

Minimal API

After completing the WebApplicationBuilder and building the WebApplication, the middleware is configured. Using a minimal API, a group for the route /todos is added. A HTTP GET request returns five random todos. Another API is available to return a single todo.

TODO Minimal API

Publish AOT

Building and running the application using Visual Studio or the CLI with dotnet build and dotnet run works as usual. The change for AOT is done with a publish step. The project file contains the entry <PublishAot>true</PublishAot>. This enables publishing the application using the AOT compiler.

Using dotnet publish now creates a binary executable file Using .NET 8 preview 3, the file size is slightly above 11 MB. A .NET runtime is not needed to run the application. Starting TodoAPI.exe starts the application – and this is a lot faster than the startup time of the application without AOT. Check the Microsoft Learn documentation for differences on startup time and memory consumption with the links below. Microsoft documents memory usage changes without or with AOT from 86 MB to 40 MB, and a startup time change from 161 ms to 35 ms. Impressive!

Take away

.NET 8 is coming with great improvements, a few have been shown here such as a slim builder with ASP.NET Core, or the Shuffle method with the Random class. The biggest change of course is AOT. .NET 7 started with support for AOT compilation. Using .NET 7, AOT only works in a few scenarios, for example creating class libraries that can be used with C++ applications. .NET 8 will add support for many more scenarios when AOT can be used. The project template for to create an API is a great example for this. Looking into the documentation what’s not (yet) working (see the link below), authentication are not yet supported, but JWT is coming soon, Blazor Server, SignalR, and MVC are listed as not supported. What’s already working is gRPC, the minimal API, response caching, health checks, web sockets, and more. Looking forward for more enhancemens coming with .NET 8.

Enjoy learning and programming!

Christian

If you like this article, please support me with a coffee. Thanks!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK