Q:

Should you validate route parameters or let them fail with a 404?

So this is an example endpoint to fetch one user by its username
[HttpGet("{username}")]
public async Task<ActionResult<object>> GetUser([FromRoute] string username)
{
    // ...
}

Regardless of the value of username the database will either find and return a user or null. But you know that a username has validation constraints like

max length of x
no special characters
...

So you could also add a validation route constraint e.g.
[HttpGet("{username:maxlength(20)}")]

or make use of data annotations like
[FromRoute][MaxLength(20)] string username

but then you have to do it for every endpoint. The advantage is that bad parameter values will never touch the database so you might increase the performance because the request gets denied. The bad thing is that you will have to maintain all these endpoints with extra validations instead of saying "I don't care for the value, the database will find it or not.".
Are there any best practises which approach should be considered?

A:

If you want to return a meaningful error message you'll probably want to add validation. Every application I've worked on has done some request validation and returned an error message before attempting to process the request. This helps client developers or users retry with correct data instead of calling first line support complaining something is broken.
In this specific case I'd be careful about what you return. You don't want to allow an attacker to enumerate your users collection by returning too much info. For example, returning "invalid username" when the validation rules are not met but "user not found" when they are may allow an attacker to reduce the total possible number of usernames they have to brute force to enumerate your users. This is probably more important when validating passwords but something to consider.

