REST HTTP response code for missing parent resource
NO: Rule out the 400 Bad Request as all the requests, which you have mentioned, are valid.
NO: To add some spice: I've seen a 409 Conflict being returned in similar cases. It appears inappropriate in your situation though as you clearly indicated that a resource is missing.
YES: A 404 Not Found is the most appropriate response if your resource does not exist. It doesn't matter if it ever existed or not. The 404 indicates a "sorry, resource unavailable". I would add an error message to be precise about which resource is missing so that your API consumers can handle the situation better.
MAYBE: A 410 Gone is a specific case of a 404. It should be raised if the resource is unavailable and it existed before and it will (practically) never exist again. So no matter how often and when you try to get the resource, you'll never get it again, but in the past, you may have been able to get it. Same thing here: if you decided on a 410 consider adding a precise error message.
On a personal note:
- I have never seen a practical useful situation of a 410 Gone hence I avoid it and recommend my teams not to use it unless they can come up with a real good reason. It appears a little academic. In most cases, a 404 and 410 will be dealt with identically by your API consumers. They most often don't mind/care. I can only see rare edge cases to make valuable sense of a differentiation.
- A DELETE often doesn't delete a resource. They get inactivated (made unavailable), but they are still available technically. If there's any chance that a resource may become available again, such as via a new feature called "return all recently deleted resources", a 410 would be already misleading.
- A 410 also states that that resource did exist in the past indeed. From a data securities point of view, you could argue that information should kept internal and should not be exposed. In these cases, a 410 becomes a general no-no for your API.
A thing to keep in mind: the HTTP response, including the metadata, which includes the status code, are specific to the requested resource, not some implicit hierarchy of things.
Which is to say
GET /users/{userId}/accounts/{accoundId}/logs/{logId}
requests: a current selected representation for the target resource. See RFC 7231; in particular, the request doesn't ask about representations of any of these:
/users/{userId}/accounts/{accoundId}/logs/
/users/{userId}/accounts/{accoundId}/
/users/{userId}
...
It's much simpler than that - can I have what I asked for? And the origin server provides a response, which may be a current representation, or it may be a message explaining that no such representation is available.
The fact that no representation of /users/{userId}/accounts/{accoundId}/logs/{logId}
is available because /users/{userId}/accounts/{accoundId}
does not exist is an implementation detail.
404 is normally what you would want to use as a status code to announce that no current representation of the target resource is available. Any explanation for why this is the case would normally go into the message body. For instance, you might describe it using problem details.
The server is not obligated to send an expired representation of a resource just because it happens to have one lying around (again, the cache is an implementation detail).
410 is almost the same thing; it's effectively an advisory that the client can mark its bookmarks as deprecated.
400 is a perfectly reasonable way to punt if you can't find a status code that better fits the semantics of the message in the payload. But I wouldn't use if for this case where 404
does actually fit your needs.