HTTP status in case I don't want to support search on one or more fields

Viewed 37

I have implemented POST /orders and GET /orders/{id} APIs successfully. Now I want to create one search API.

My resource has the following fields: customerId, orderId, customerName, orderName, and orderType.

I want to create one more get APIs based on fields present in resource. So, I designed it like: GET /orders?orderType=ABC&customerName=Xyz

But I want to restrict search on some params. In the above case say I want to restrict search on orderName (although the field does exist).

Now if you hit GET /orders?orderName=DEF I will respond back with search not supported.

What should the HTTP status code be in this case?

I am concerned about using 501, as this is more related to HTTP status itself. Same for 422, it is related to the entity coming in the request code. Can't send 404 as data does exist. Need some clarity on these.

And what should I finally implement?

2 Answers

Now if you hit GET /orders?orderName=DEF I will respond back with search not supported.

What should the HTTP status code be in this case?

404 Not Found

The 404 (Not Found) status code indicates that the origin server did not find a current representation for the target resource or is not willing to disclose that one exists.

In other words, the status code specifically identifies the target-uri as the problematic part of the request.

5xx is off the table, because this is an issue that can be fixed by changing the request.

Can't send 404 as data does exist.

Of course you can.

The important thing to recognize is that HTTP status codes are part of the transport documents over a network domain, not your application domain.

With the transport documents over a network domain, 404 means "the identifier you requested does not have a document associated with it". And that is precisely the case you have (from the perspective of a general purpose HTTP component).

The uniform interface of HTTP is that of a document store; pass in a key, receive the document stored using that key. When we report errors, we report them using the same semantics as a document store. KEY_NOT_FOUND, in HTTP, is 404.

Can I send 404 with the message kind of - 'Intentionally not supported' or something?

Yes, you can do that.

The mechanism is described in RFC 7231

The 4xx (Client Error) class of status code indicates that the client seems to have erred. Except when responding to a HEAD request, the server SHOULD send a representation containing an explanation of the error situation, and whether it is a temporary or permanent condition.

In other words, you provide in the response body a description of the problem. The 404 status code is metadata that tells general purpose components (like a browser, or a web cache), that the entity included in the response is an error, and NOT a representation of the resource.

You might, for example, explain the error situation using a problem details document.

While I agree that 404 could be considered technically correct, I would have a concern: What does this communicate to a developer?

Even though the 404 refers to the entire URL

/orders?orderName=DEF

It wouldn't be farfetched that a programmer to assume that the 404 actually applies to /orders with any query parameter.

Many systems will ignore incoming unrecognized query parameters, so one option is to just ignore it. If you want a strict error, I would be tempted to use a more generic error like 400 Bad Request, as I think that this will improve the developer experience and is less surprising.

I think reducing surprise is more important than being technically correct (in this case).

Related