0
votes

Let's say that I have a detail page for items: /items/{id}. A user can of course try any random id, but if he doesn't have access to that item, I return the detail page with no data, which is not very nice. I'd rather just return 404 or 204 instead. However, with Breeze Web API, I'm returning an IQueryable, so I can't return an error, and I'd have to handle the empty set on the client. What is the nicest way for doing this? I'm thinking of checking if the result is empty and then redirecting to a custom 404 page, but was wondering if there's a better way?

Thanks

2

2 Answers

1
votes

When you write a service/Web API controller method that returns IQueryable, you have made a conscious decision that your HTTP resource is a collection. The collection may be empty ... but an empty collection is as valid a resource as a full collection. The collection was found and the correct response is 200, not 404.

If you're HTTP request was for a specific item (eg.., you had an endpoint designed to return a single object whose route was something like ~/customers/:id), then returning an HTTP response with status 404 makes sense. You can have both kinds of endpoints if you wish. Breeze doesn't force you into IQueryable. That is just an option. You can have a mix of both kinds of endpoints.

For me, the larger concern is a possible confusion between data (the customer(s)) and UI (the page). The Web API isn't returning a page; it's returning data.

I'm assuming you're building a "Single Page Application" which has a detail screen. You do indeed have to decide what should happen if you navigates to a detail screen, try to fetch the entity for that screen by Id, and discover that such an entity does not exist. Now you have to decide where to go.

That decision is independent of the HTTP status code. You can re-direct your client-side screen to a safe location (e.g., the list of Customers) without worrying about HTTP status codes. HTTP status codes are part of the HTTP protocol for communication over the web. Your application's own client-side screen navigation isn't crossing the web and there is no need (and no point) to adopting that protocol.

You should be just fine detecting that the Web API returned an empty collection. There is no embarrassment. The HTTP police will not arrest you. Just re-direct as appropriate.

1
votes

You can throw a 404 error from within your IQueryable method like this

[HttpGet]
public IQueryable<Customer> CustomersWithHttpError() {
  // throw new HttpResponseException(HttpStatusCode.NotFound);
  var responseMsg = new HttpResponseMessage(HttpStatusCode.NotFound);
  responseMsg.Content = new StringContent("Custom error message");
  responseMsg.ReasonPhrase = "Custom Reason";
  throw new HttpResponseException(responseMsg);
}