I switched back to node.js with fastify and wrote my app in an hour.
I really like C# for cli and windows desktop applications, but I probably won’t touch it for the web in the next few years.
I switched back to node.js with fastify and wrote my app in an hour.
I really like C# for cli and windows desktop applications, but I probably won’t touch it for the web in the next few years.
The issues you had could be attacked by navigating through this section of documentation, diving into the tutorial referenced in the beginning of the Overview section and the subsequent sections: https://docs.microsoft.com/en-us/aspnet/core/web-api/?view=a.... This is not necessarily in defense of c# and dotnet, but this reads like you barely spent any time trying to digest the documentation.
Then once you need to go beyond the standard libraries it becomes a nightmare to deal with. In some cases, like extending the AD libraries, it’s sort of easy to extend classes with methods but the documentation on how to do so tends to assume a lot of domain knowledge. In other cases like if EF’s standard functionality isn’t enough for you, or you need to deal with weirdly formatted XML or non standard SOAP requests (don’t ask) it can be such a nightmare that it’s sometimes easier to write a micro-service in another language to do the “translation”.
I think it speaks of a language that doesn’t see too much use by its own creators. I may be wrong on that, but having build a lot of things for Azure, Typescript has often felt more like a first class citizen than C#. Obviously not for everything, far from it, but sometimes and those sometimes are enough to make C# troublesome because unlike things like typescript that are great second class citizens in the Microsoft ecosystem, C# isn’t. It either fits really well or you have to fight it.
Maybe that is because we didn’t have a fascist linter for C# the way we do with Typescript, but it’s always been much, much, harder to get people to make “good” C# code in my experience. It hasn’t been hard to have the build things in C#, but it’s been hard to get people to build things the same way so that they can work on each others code flawlessly. So hard that I would never again consider using resources on it until developers drop significantly in pay, which isn’t likely to happen until I’m retired, if ever.
I wonder if it has to do with regional differences. I’m Danish, everyone (there are odd cases, but it’s more “everyone” than “almost everyone”) here has a CS degree and often they’ve been taught Java, sometimes C# but poorly, while obtaining it.
For me, fsharp interactive is one of the best prototyping experience I have ever experienced.
And it says right at the bottom, that OpenAPI and model binding is not supported in their route to code feature.
I initially googled how to create a simple json api, and that’s the documentation which I found. Looks really easy in the beginning, but after you’re done with your routes, you’ll read at the end of the documentation, that OpenAPI generation, model binding etc is not supported. I blame that the guide‘s title is misleading and - of course - that I should’ve read till the end before actually following any step of that tutorial.
For example, the secret incantations required to output a mere string as raw json mimetype or log incoming deserialization errors* are unintuitive and very labourious - see InvalidModelStateResponseFactory. Or that I had to create a custom output formatter to output raw json. Why? Sometimes I just want ASP.NET to get out of my way and it's not trivial to tell it to let go.
* For example, url?parameter=1 for a boolean parameter, which would have worked with .NET Framework but won't for .NET Core/.NET.
As per another comment after having seen JS devs switch to F# for very large professional application and not wanting to go back I feel its fine for web. YMMV.
If you use the templates provided by .NET Command Line Interface or Visual Studio, you'll get this all baked in & setup.
VS also added a very nice feature where it suggests & imports popular packages if you type a method on a type that's well known. If you already have it added to your project but need a using statement in this file, it'll pick that up fast as well.
They've also improved their docs quite a bit from years ago with lots of good examples for common things.
- Templates are no substitute for intuitive and minimal code for a number of reasons. (e.g. how to extend, how to customize, confidence that it isn't brittle if I change one thing, etc etc). If a template doesn't have the exact variation you want (e.g. a faster logging library) the learning curve is very high for a newcomer .NET dev. NOTE: I think this applies to some other OO languages too.
- Suggesting popular packages and namespaces is a great tooling improvement. But it could also imply a closed wall garden. The fact that other non C#/Java like languages don't have this problem even with something as minimal as VS Code as your IDE shows that the tooling is trying to cover over a language and/or library problem. With the Java/C#/other old OO lang workflow you need the knowledge you need to use the library itself (convention based, which class, which extension method, which namespace for that object to configure this feature, startup class conventions, etc). It isn't discoverable even with the packages imported. Remember just getting Serilog working in new ASP.Core and it taking a day or so with all the packages, config, etc etc if you don't already know what you are doing.
I like the improved docs. But fundamentally simplification/minimization is better. I think the dev workflow that means I don't need these tooling improvements is still a better experience. I like .NET, but I do understand when using other languages they seem to not have these issues despite not having the uber tooling that C# has. They don't have package suggestions, they barely even have auto complete yet the library design feels a lot more intuitive.
I can look up say a Fastify, Golang, even some F# examples with something like Giraffe and get a web app quickly with little code and no convention magic with everything being explicit yet concise. No fancy attributes I need to remember, no conventions in my startup classes I need to understand if any customisation, even dep injection is something to learn from people coming from some other platforms rather than just standard library calls composed together.
I actually like the .NET platform, don't get me wrong, I do think it is one of the best web platforms right now. Its more intuitive than Spring/Java as a comparison but that isn't saying much IMO. For newcomers I think the user experience to newcomers who are used to a lot less ceremony could be improved further. My first suggestion would be less "developer headspace required" to get started. On a personal note I think natural F# code tends to favor this from the teams I've been in but can't put my exact finger on a reason as to why - it feels more like coding Go/JS to me at least than C#.
For newcomers, I would say the best user experience (no matter language/framework) is provided by code hinting such as GitHub GitLens & competitors do. If I'm using an unfamiliar framework/language it's great at suggesting what I might want without me having to search.
You might really like the new .NET minimal APIs that are being built for web development. They're very similar to a Node.JS style of API.
In regards to logging specifically, I've found swapping logging tools fairly easy & straightforward as far as adding the logging in the code base. If there has been anything challenging it's been outside the code base & setting up the infrastructure or learning the logging's reporting tools. I'm curious what was challenging for .NET with you. It's usually as simple as using Ilogger no matter the tool & writing a few lines in the program.cs file.
https://docs.microsoft.com/en-us/aspnet/core/web-api/route-t...
That said, you may take a look at my small very early state pet project `tonehub`[1], which can be seen as pretty modern CRUD Web API in 2022, utilizing swashbuckle for OpenAPI, JsonApiDotNet for CRUD, Entity Framework 6 for Database, HostedServices for background tasks and some other nice concepts (DI / IoC, Options Pattern, FileStreams, etc.). I could also use SignalR for WebSockets / Realtime, integrated OpenID/OAUTH2 Authentication, FluentValidation for validation, Api Versioning and much more.
I've never accompilished something like this with this small amount of code...
Failing to find the differences between them will impede learning in general.
With .NET 6 SDK, 'dotnet new webapi' will give you a template project that does everything you listed save for extended validation logic which you can easily add with 'FluentValidation'.
In addition, to run ASP.NET Core nowadays you only need:
var builder = WebApplication.CreateBuilder();
var app = builder.Build();
app.MapGet("/posts/{name}", ([FromRoute] string name) => /* controller logic, classes will be serialized as JSON */);
await app.RunAsync("http://localhost:8080"); dotnet new webapi -minimal
This will scaffold a project which is more or less the exact same as Flask, Express, or any other "easy" framework.OpenAPI output is built-in, but tooling for development does require a bit of knowledge (agree that Microsoft would benefit from making this work out of the box).
A small repo here showing how to connect OpenAPI and front-end TypeScript client generation: https://github.com/CharlieDigital/dotnet6-openapi
services.AddSwaggerGen();
app.UseSwagger();
app.UseSwaggerUI();
Since I'm already spawning a TestHost and trying out various API calls, one of these tests basically does "curl $host/openapi/openapi.json | diff ./docs/openapi.json". If it spots a change and fails the test, I check that the difference is expected, and if so I temporarily enable and run a different "test" which actually writes the updated file.
They are existent and good.
Of course you did. You're on familiar ground.
Personally I'm also familiar with .Net and could do the same in that stack in that timeframe too. Like with many things worth doing, it requires a time investment to reach that point.
Having said that, .Net APIs support JSON request/response out of the box, validation is available on the models in seconds using a powerful set of attribute annotations, and Swagger is also built in out of the box. And API projects can seem similar to MVC ones as they use the same framework and libraries, but whilst the out of the box APIs have controllers they don't have views.
So to repeat, it's down to familiarity.
Edit: For clarity this is not a criticism. I fully understand why these things may not be obvious up front. Both the validation attributes and the Swagger URL for the default support are not obvious to the newcomer.