> I was surprised how much was included and "just worked".
A simple HTTP server? Maybe I'm missing something, but when I needed it I hadn't found one.
I believe, the closest it has is System.Net.HttpListener which is a very different thing from your typical Golang's net/http.Server or python's http.server.HTTPServer.
I believe at some point they had switched from HTTP.sys to Kestrel, so at least it doesn't need the admin privileges anymore. But this whole thing is so much related to ASP.NET it's pretty hard to figure out how to create a simplest HTTP server without anything else forced upon you (no services, no "web applications", no router, just plain and simple bare HTTP protocol handler). So my impression is that maybe .NET can make certain complex things easy, but it has some issues with keeping simple things simple.
If for some reason you don’t want the framework to handle things like routing or request/response deserialization/serialization then you can go bare bones and implement everything via custom middleware: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/m...
… how often are you hand-parsing HTTP requests and hand-crafting HTTP responses one character at a time?
Productive devs want the request/response wrapper objects and routing constructs to handler methods to get work done and can still drop down into fine-grained request/response crafting as and when required.
That's exactly what I don't do, and what I want to see available in a standard library.
But I quite frequently implement custom request handling before any routing happens (if there's even any routing). That's super easy to do in Go, Python or Rust, but when I needed something comparable in C# I haven't found any similar composable independent pieces that I can join together in a way I see fit.
As a sibling commenter mentioned, there’s a minimalist functional web server available out of the box, that can later have other more complex components added on:
I'm sorry, I think I really must be missing something out and/or explained myself poorly, but I don't see how this is comparable... Doesn't `WebApplication.CreateBuilder(args).Build()` creates a whole web application type thing? In my understanding it's something comparable to `gin.Default()` or `flask.Flask(__name__)`, rather than lower level basic `http.Server{Addr: addr}` or `http.server.HTTPServer(address)` (which still doesn't require any manual HTTP protocol parsing).
And this stuff is ASP.NET Core, not a bare .NET [Core], isn't it? What I'm talking about is something comparable to just Kestrel, except that I failed to find any documentation on using it "raw" without the whole ASP.NET thing (maybe I misunderstood what it is and it's tightly coupled with the whole framework?).
WebApplicationBuilder is the mechanism for configuring the kestrel web server. Kestrel is the foundation of Asp.Net Core, there's no separating the two. But Kestrel is a totally modular system. If you configure your request pipeline with a single custom middleware then that is literally the only thing the server is running. If you use only minimal APIs then the middleware that handles their routing is the only thing running. Asp.Net Core has dozens of bells and whistles but none of them affect your app if they aren't part of your request pipeline.
WebApplicationBuilder itself is mostly the base .NET Generic Host [1] (which is "bare" .NET and is used as a common host for dependency injection plus common utilities such as configuration and logging) plus activating the Kestrel hooks for HTTP middleware. Kestrel even at its most "raw" is always slightly higher-level and closer to Flask or Express (JS) as a middleware-focused HTTP execution engine.
(This partly reflects the classic HTTP.SYS role in IIS/Windows as well, because Window's HTTP.SYS is surprisingly high level for a "raw" kernel component for hosting web servers. From my understanding, most of "Kestrel" under-the-hood is just a cross-platform semi-recreation of the HTTP.SYS abstraction machine on top of things like but maybe not exactly libuv/ioring. So yes, everything is "naturally" higher level in .NET than Python's lowest level just because it assumes a higher-level "OS server" base.)
Also, yes, the boundary between "Kestrel" and ASP.NET is really hard to define at this point. Almost all of ASP.NET is just "Express-style" (though much of these middleware patterns in ASP.NET I believe predate Express) middleware that is cumulatively stacked on top of each other as you add more high-level ASP.NET features, and at this point all of them are just about optional depending on what you are looking to do.
Even many alternatives to ASP.NET at this point are built on top of the core basics like WebApplicationBuilder, they just diverge at which sets of middleware stack on top of that.
I don't have any issues with the IHost and builder patterns. I actually like those - although I've only used the very basics, so I don't really know about the intricacies and possible drawbacks.
Thanks for clearing my misunderstanding about the coupling. I really thought Kestrel was something different, have not expected it to be this high level. It being a replacement of HTTP.sys totally makes sense, of course.
There's an ancient historic low-level API, that I just remembered, which you can explore that still remains around for backwards compatibility but isn't recommended for new code: Kestrel was (via a long scenic route) forked from System.Net.HttpListener [1] which is the closest to a strict bare-bones HTTP.SYS wrapper that has existed in .NET.
There's a long issues thread on HttpListener should be more strongly marked deprecated [2] to avoid people accidentally using it despite today's recommendations to use Kestrel/the "Most Core" parts of ASP.NET. One fun part of the thread is an example repo of the absolute most "bare-bones" and "raw" Kestrel bootup possible [3], including a "TODO: implement TLS handshake here" bit.
>In my understanding it's something comparable to `gin.Default()` or `flask.Flask(__name__)`, rather than lower level basic `http.Server{Addr: addr}` or `http.server.HTTPServer(address)` (which still doesn't require any manual HTTP protocol parsing).
This works in practice, but comparing to Python, it's like pulling in Django when all I need is in the standard library (although some people do and their projects are successful, that's for sure). I just don't want to bring a whole industrial grade CNC machine to do something a handsaw would be perfect for.
A simple HTTP server? Maybe I'm missing something, but when I needed it I hadn't found one.
I believe, the closest it has is System.Net.HttpListener which is a very different thing from your typical Golang's net/http.Server or python's http.server.HTTPServer.
I believe at some point they had switched from HTTP.sys to Kestrel, so at least it doesn't need the admin privileges anymore. But this whole thing is so much related to ASP.NET it's pretty hard to figure out how to create a simplest HTTP server without anything else forced upon you (no services, no "web applications", no router, just plain and simple bare HTTP protocol handler). So my impression is that maybe .NET can make certain complex things easy, but it has some issues with keeping simple things simple.