Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EPIC: Support publishing ASP.NET Core API apps with Native AOT (WIP) #45910

Closed
5 tasks done
Tracked by #47240
DamianEdwards opened this issue Jan 6, 2023 · 20 comments
Closed
5 tasks done
Tracked by #47240
Assignees
Labels
area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc Epic Groups multiple user stories. Can be grouped under a theme. Priority:0 Work that we can't release without Theme: cloud native
Milestone

Comments

@DamianEdwards
Copy link
Member

DamianEdwards commented Jan 6, 2023

Overview

.NET 7 introduced support for publishing .NET console projects as native AOT, producing a self-contained, platform-specific executable without any runtime JIT. Native AOT apps start up very quickly and use less memory. The application can be deployed to a machine or container that doesn't have any .NET runtime installed. In .NET 8 we will extend support for native AOT to ASP.NET Core, starting with cloud-focused, API applications built with Minimal APIs that meet expectations regarding published file size, startup time, working set, and throughput performance.

Scope

As stated, the primary focus for .NET 8 will be on enabling native AOT publish of ASP.NET Core API applications using Minimal APIs. "Support native AOT" in this context means ensuring that projects can enable native AOT publish via the <PublishAOT> project property and the resulting development experience leads developers to producing native AOT published applications without build, publish, or runtime warnings and errors. This means that the majority of foundational feature areas of ASP.NET Core and .NET will need to be updated to support native AOT, including:

  • Hosting APIs including WebApplication, etc.
  • Kestrel HTTP server
  • Configuration & Options
  • Logging
  • Dependency injection
  • Common middleware
  • Authentication and Authorization
  • Minimal APIs
  • Health Checks
  • Data access with ADO.NET (SQLite and PostgreSQL as the primary targets)
  • OpenAPI support
  • Observability and diagnostics

Additionally, as a secondary goal, we will make progress towards enabling native AOT publish for the following feature areas:

  • gRPC
  • SignalR
  • MVC Web APIs
  • Entity Framework

The following feature areas are out of scope for native AOT support for now:

  • MVC views and Razor Pages
  • Blazor Server

Development experience principles

Native AOT has limitations that mean certain APIs and code patterns in .NET are not supported when publishing native AOT. These include features that rely on runtime JIT, e.g. dynamic code generation and compilation, assembly loading, etc., as well as patterns that result in code being trimmed away by the native AOT compilation process that is needed to execute the application, resulting in runtime failures.

In adding support to ASP.NET Core for native AOT, we must ensure that the development experience is such that developers can reasonably determine how their app will run once published as native AOT. Where current APIs and features are designed in such a way that are incompatible with native AOT, we will utilize tools including source generators, analyzers, and code fixers, to allow existing APIs to work with native AOT or for developers to update their apps to work with native AOT in a reasonable fashion.

Stages

Stage 1

Stage 1 of this effort will be to enable creation of ASP.NET Core API projects using a new project template, enabled for native AOT, that can be built, published, and run without any warnings or errors, and that meets the defined metric targets for executable file size, startup time, working set, and throughput.

Metric Targets

These are primarily Linux-focused as that's the primary deployment target, but size on Windows on macOS will still be tracked and kept in line with these targets as it often contributes to perception during candidate platform investigations.

  • 10 MB executable file size
  • <50 ms startup time (ready to accept first request)
  • <50 MB working set memory footprint (ready to accept first request)
  • <50 MB working set memory footprint (after handling load test)
  • Within 5% of default CoreCLR RPS on Citrine perf environment
    • "default" here means compared to the default configuration of a CoreCLR-based deployment of the app, e.g. including tiered JIT

Stage 2

Stage 2 builds on stage 1 to enable more "real-world" ASP.NET Core API applications to be native AOT published. These applications will use more features typically associated with running API applications in cloud environments including AuthN/Z, data access, OpenTelemetry, etc. The TrimmedTodo API application will serve as the initial example of this kind of application.

Stage 2.a

Feature areas to be made compatible with native AOT in stage 2.a as part of .NET 8:

  1. Configuration & Options inc. binding and validation
  2. Data access via ADO.NET using the Npgsql provider (for PostgreSQL) and, as a secondary priority, Sqlite
  3. Authentication, using the JWT handler, and Authorization using existing ASP.NET Core authorization features
  4. Health Checks, with a primary focus on the in-framework providers and cloud native deployed scenarios, e.g. readiness & health probes
  5. Open Telemetry,

Metric Targets

These are primarily Linux-focused as that's the primary deployment target, but size on Windows on macOS will still be tracked and kept in line with these targets as it often contributes to perception during candidate platform investigations.

  • 20 MB executable file size
  • <150 ms startup time (ready to accept first request)
  • <60 MB working set memory footprint (ready to accept first request)
  • <60 MB working set memory footprint (after handling load test)
  • Within 5% of default CoreCLR RPS on Citrine perf environment
    • "default" here means compared to the default configuration of a CoreCLR-based deployment of the app, e.g. including tiered JIT

Stage 2.b

Feature areas to be made compatible with native AOT in stage 2.b, likely beyond .NET 8. Note that work towards native AOT compatibility for these areas will likely begin in .NET 8, but not be completed:

  1. OpenAPI/Swagger
  2. Validation of minimal API arguments
    • This is a new feature area for .NET 8 that if delivered should be made native AOT friendly
  3. SignalR
  4. MVC Web APIs
@DamianEdwards DamianEdwards added Epic Groups multiple user stories. Can be grouped under a theme. Theme: cloud native labels Jan 6, 2023
@DamianEdwards DamianEdwards added this to the 8.0 milestone Jan 6, 2023
@DamianEdwards DamianEdwards self-assigned this Jan 6, 2023
@DamianEdwards DamianEdwards changed the title Epic: Support publishing ASP.NET Core API apps with Native AOT (WIP) EPIC: Support publishing ASP.NET Core API apps with Native AOT (WIP) Jan 6, 2023
@DamianEdwards DamianEdwards added Priority:0 Work that we can't release without Cost:XL labels Mar 6, 2023
@sajjadarashhh
Copy link

There is any native aot for blazor wasm??
Native aot for that can be very very hopeful and nice solution for performance issues like size and startup time

@DamianEdwards
Copy link
Member Author

DamianEdwards commented Mar 7, 2023

@sajjadarashhh Blazor WebAssembly runs on Mono which has its own native compilation toolchain, separate to native AOT for .NET.

As such, Blazor WebAssembly already supports AOT compilation: https://learn.microsoft.com/aspnet/core/blazor/host-and-deploy/webassembly#ahead-of-time-aot-compilation

@sajjadarashhh
Copy link

@DamianEdwards but native aot is not equal to that when we have that dotnet.wasm must be smaller and quicker at startup

@DamianEdwards
Copy link
Member Author

@sajjadarashhh at any rate, this issue is about enabling native AOT for ASP.NET Core apps targeting CoreCLR. Please log a separate issue regarding performance and size of Blazor WebAssembly AOT if you wish to discuss that.

@GerardSmit
Copy link

I've tested NativeAOT for ASP.NET Core in .NET 8.0 preview 2 with my "WebForms in .NET" project, which works 🎉.
Incase you want to read more, you can click here.

I've put it in a spoiler so this issue doesn't get too big.

It almost worked without any issues. The only issue I had is that the trimmer removed public constructors from controls since they aren't added in the service collection; I'm using ActivatorUtilities.CreateInstance.

So I've modified the source generator that assembly attributes are being added for every control in the project:

[assembly:WebFormsCore.AssemblyViewAttribute(@"Example.aspx", typeof(Tests.CompiledViews.Example_aspx))]

which includes the DynamicallyAccessedMembers-attribute:

public AssemblyViewAttribute(string path, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type);

After that, everything works as normally. Now I have WebForms in .NET with NativeAOT (sounds cursed but all in the name of science!) 🎉. And the size is 15 MB (~6 MB without ASP.NET Core and DI).

image

I'm amazed how it just works. Great job team 👍

The source-code can be found here: https://github.com/WebFormsCore/WebFormsCore/tree/main/examples/WebFormsCore.Example

@JinShil
Copy link

JinShil commented Apr 8, 2023

The following feature areas are out of scope for native AOT support for now:

  • MVC views and Razor Pages
  • Blazor Server

That's very unfortunate. I have Blazor Hybrid (WebKitGTK on Linux) applications running on ARM64 that take much too long to start up. If I publish them with NativeAoT, they start up very quickly, but they don't render the UI or they segfault.

@mitchdenny
Copy link
Member

That's very unfortunate. I have Blazor Hybrid (WebKitGTK on Linux) applications running on ARM64 that take much too long to start up. If I publish them with NativeAoT, they start up very quickly, but they don't render the UI or they segfault.

Thanks for the feedback @JinShil - getting ASP.NET running on the native AOT deployment model is a process. As we achieve each milestone, we can re-evaluate features that are currently out of scope.

@hez2010
Copy link
Contributor

hez2010 commented May 17, 2023

Would like to see NativeAOT support for razor component too.

@dameng324
Copy link

The following feature areas are out of scope for native AOT support for now:

MVC views and Razor Pages
Blazor Server

Is there any plan to support Blazor Server with NativeAOT ? maybe .net9 ?

@DamianEdwards
Copy link
Member Author

DamianEdwards commented Oct 13, 2023

Is there any plan to support Blazor Server with NativeAOT ? maybe .net9 ?

Not concrete yet, but it's certainly in the list of areas to consider.

@eerhardt
Copy link
Member

@DamianEdwards - can this Epic be closed now that 8.0 has shipped?

@mkArtakMSFT mkArtakMSFT added the area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc label Nov 17, 2023
@SquareHatLtd
Copy link

Will AOT ASP.NET Core ever support Https.

Our company (as many financial sector companies have) is a policy that all data has to be encrypted both in flight and at rest. It would be a shame to miss out on all the AOT goodness simply because HTTPS is not supported.

Thanks Stephen

@martincostello
Copy link
Member

My understanding is that is supported in .NET 8: Reduced app size with configurable HTTPS support

@DamianEdwards
Copy link
Member Author

@SquareHatLtd HTTPS is supported, but if using WebApplication.CreateSlimBuilder you need to add HTTPS support for Kestrel back in as it's not included in the defaults, e.g.:

var builder = WebApplication.CreateSlimBuilder(args);

builder.WebHost.UseKestrelHttpsConfiguration();

@w-as
Copy link

w-as commented Nov 26, 2023

The team has done some truly remarkable work on this feature, thank you!
Just checking whether there is any update on plans for Stage 2.b, particularly w.r.t OpenAPI/Swagger.
Thanks again!

@eerhardt
Copy link
Member

@NotTsunami
Copy link

@w-as - do you need your OpenAPI/Swagger endpoint in production? One approach we took in the TodosApi benchmark app was to make it a development-only time feature. See

Chiming in here. In some of our apps, we make it development-only as well. But we provide a lot of utility via our OpenAPI/Swagger endpoints and we actually have a customer that prefers we ship with Swagger in prod. There are absolutely alternatives to this, but it would be nice to see support at some point for OpenAPI in Native AOT (although it is not at all necessary, would be extra brownie points). The bigger blocker for us in moving some apps to Native AOT is lack of SignalR support. Hoping to see this roadmapped soon!

@w-as
Copy link

w-as commented Jan 12, 2024

@w-as - do you need your OpenAPI/Swagger endpoint in production? One approach we took in the TodosApi benchmark app was to make it a development-only time feature. See

I'm sorry I missed your response back in November, thank you for the suggestion of dev-time only. We do currently publish the OpenAPI/Swagger endpoints in production yes, however it may be possible to create clients based on dev-time specs so will investigate that, thank you.

@Hylaean
Copy link

Hylaean commented Mar 27, 2024

Great job there!
Is Stage 2.b targeted for .NET 9?
SignalR at least?

@eerhardt
Copy link
Member

Is Stage 2.b targeted for .NET 9? SignalR at least?

Check out the update to this issue: #41704 (comment). My plan is to get SignalR support with the JSON protocol in for .NET 9 preview 7.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc Epic Groups multiple user stories. Can be grouped under a theme. Priority:0 Work that we can't release without Theme: cloud native
Projects
None yet
Development

No branches or pull requests

17 participants