Consider the following URL
This is a sample example, I'm using customers and order here, for an easy understanding of the setup.
In the order controller:
[HttpGet("~/api/customer/{customerId:int}/orders", Name = nameof(GetOrdersByCustomerIdAsync))]
[ProducesResponseType(200)]
[ProducesResponseType(404)]
public async Task<ActionResult<IEnumerable<OrderListItemResourceModel>>> GetOrdersByCustomerIdAsync(int customerId:int){}
Question 1: Should this method actually exists in the CustomerController or the OrderController? For me it made more sense in the Order controller as I do return orders here, but the routings is that of a customer, ...
Question 2: In my Core & Data layer, the Order object has a customer linked to it. The binding model in my api layer has an integer CustomerId Where do I validate that the given customer id actually is from an existing customer? Is it ok to validate this in the controller by calling the customer service? If so, can I just return NotFound()? Or should I do something else, so that it is clear to the user that it was the customer that is not found?
Again, this is a fictional example.
Question 1 - ~/api/customer/{customerId:int}/orders
in Customers controller or Orders controller?
Customers Controller
Here you are accessing orders as a property of a customer, therefore that action falls under customer controller. But if you were accessing, say ~api/orders
this would fall under Orders controller as this is accessing orders resources independent of any other resource.
Question 2 - where to validate customer Id against existing db records
This is rather dependent on your implementation. Asp.Net Core provides functionality to do this from virtually anywhere - Filters, Services, etc - via dependency injection. So this depends on the structure of your application.
Whether you can return NotFound()
?
Yes.
If customerId does not match any existing customer, NotFound would be the appropriate response according to the HttpStatusCode 404 Description.