I've been using PHP for the past 5 years or so, and I'm taking a look at C#, which I last used 5-6 years ago.
A lot has happened, it seems.
One of the greatest pains was threading issues (locks and mutexes, ugh) and it looks like async
and await
will make for a more painless experience in that department, so that's good.
The platform and the new .NET Core run-times are now cross-platform with Linux and Mac support, so that's a huge plus.
But where's the simple, elegant, straight-forward, no-frills, no-bells, no-whistles HTTP kernel I'm looking for?
These past years, with the PSR-7 HTTP model, and PSR-15 middleware model, I've grown accustomed to a very simple and elegant HTTP abstraction consisting of a few interfaces and a trivial middleware stack - I build everything from the ground up with a DI container at the center of everything, which provides me with a huge degree of freedom, flexibility, control and ease of use, with very few moving parts, easy debugging, and nothing to get in the way of handling any special case or requirement.
Everything I can find for C# looks overly complex, bloated - everything seems to be based on the idea of "standard architecture" with a bunch of hooks and configuration that lets choose from lots of tailored options and plug things in.
After the success we've had with PSR-7/15, after seeing how happy my fellow developers are working with something much more simple and open, frankly, it would feel like a huge setback, going back to the kind of "fill in the blanks" architecture of "web" frameworks (way too broad!) that we put of with before we discovered things like Express.js, PSR-15 and similar middleware stacks on other platforms.
All I really want is a simple Request and Response model, and a very basic Request => Response
middleware abstraction (e.g. PSR-15's HandlerInterface
would do nicely) that plugs into a simple HTTP Host that does the hard work.
Surely there has got to be something like that for C#/.NET Core?
Why am I not finding it?
Top comments (3)
Something like Shelf for Dart should be possible with C# for sure - simple, clean, statically-typed. Poking through it's dependencies, this is way less code, fewer concepts and much less complexity than anything I've seen for .NET.
I had my early days of web-development with ASP and IIS 20 years ago, and I know from experience with early versions of ASP.NET MVC under IIS that Microsoft are basically infamous for complicating the HTTP life-cycle, which is really completely trivial if you think about it.
But surely there's gotta be something out there?
If not, maybe that's why so many developers still shy from .NET and C#? I mean, C# is a great language - I learned so many great things from working with this, but the complexity of IIS (which the MVC framework did a poor job at hiding at the time) is meaningless to me.
PHP is a pretty awful language - even the CGI API is terrible, but PSR-7 actually does a really good job hiding it.
That would be one option, I suppose. Just plug into Kestrel and hide it behind a really simple
Request => Response
middleware interface and forget it exists.I just hate the idea of having so much useless complexity beneath something very simple though - and not just on principle: I know from experience with PHP that having a lot of complexity in the lowest layers causes real problems. (mangled header-names in
$_SERVER
, weird edge-cases withheader()
and so on.)Surely there must be a C# user out there who feels like I do? :-)
Have a look at ASP .NET Core that now ships with Kestrel (docs.microsoft.com/en-us/aspnet/co...) as well as happy-path NancyFX : nancyfx.org/
As others have pointed out, the main problem with ASP.NET and Kestrel, is you get an entire framework with all manner of abstractions, IOC, authentication, templating, etc. etc. - and all of it is deeply coupled.
Nancy looks nice - but again, this is a framework, not a general abstraction.
I can see Kestrel being extremely valuable for it's high performance and quality - but, much like PHP, it's all highly integrated and very opinionated; it's an all-or-nothing sort of deal.
What I long for is an implementation-independent set of abstractions for (immutable) request, response, headers, URI, body, and factory abstractions for those - and a simple middleware-interface that describes the HTTP request/response exchange, nothing more.
Upon that, we can build simple middleware hosts for Kestrel, for System.Net.HttpListener, or for anything else - a host being just something that generates requests, passes them to your middleware, and emits the response.
This approach has already worked wonders on most other platforms, including at least PHP, Node, Ruby and Dart, so it's really surprising, and somewhat disappointing, not to find something like this in the .NET world. 😐