Search code examples
c#asp.net-mvc-routingasp.net-core-webapi

c# .net core 2 web api: correct HTTP result for missing parent object and / or validation?


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.


Solution

  • 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.