The issue is that this sort of validation boilerplate shouldn't have to be written. The framework should be able to figure it out from the HTTP handler declaration. I suspect this is why FastAPI got so popular in the Python world.
IMO, a lot of the JS world seems mentally fixated on express.js-levels of abstraction still. Anything more is viewed as "magic" and viewed as suspect because it requires learning.
The irony is that the "learning" just gets applied elsewhere; there are certain foundational building blocks that I think every language and platform needs once you start building "serious" applications.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/{userId}", (int userId) => userId);
app.Run();
See `int userId`? If I call this API with `http://localhost:5123/asdf`, I will get an error because the types don't match. If I call this with `http://localhost:5123/1234` it will work fine. The same would be true if I required a class `User` here. The router is able to introspect the type at runtime to determine if the types match; both basic types like this as well as complex types using the built-in serializer. It is built in.
I’m not sure why you’re so obsessed with this. You can do the same thing with any validation library in nodejs. Your exact example is possible by integrating any validation library of your choosing into a nest js route pipe. In particular primitive type validation is built into nestjs anyway
The fact that it’s built in is neat but not really important. Most people are not making thousands of toy apps. If the necessary they will integrate and move on.
There are more compelling reasons to use .net than this.