In addition to @Dherik's answer.
URIs are identifiers, so we have to keep in mind that (/a/{id}/b
is an identifier). The URI is meaningless for the WWW, and so is for the HTTP client.
404 is the right answer. In essence, the server is answering
I didn't find any resource with such id. Resource not found
1
Whether the missing resource is parent or child doesn't matter.
We, developers, see hierarchies and paths in the URI, but HTTP clients don't. In other words, HTTP is only meant to be interpreted by HTTP clients but not by humans (devs, end-users, etc).
In case of doubts, don't ask what code makes sense for you (human). Do ask, what code makes sense for the HTTP client. How do you want the HTTP client to behave?
Why? Because some status code causes these clients to perform certain operations. For example, 302. This code usually makes web browsers to redirect to a specific location (URI) informed in the response headers.
This might not be your case, but it's important to be aware. Ultimately, HTTP status codes are addressed to HTTP clients. Not to our applications. Not to persons.
1: 409 is rarely implemented as navigation error. It usually involves the execution of remote operations (delete, update, new, etc). But the URI should exist. Otherwise, 404 will prevail