Which status to return for request to invalid URL for different http methods?

16,241

Short answer: It does not have to always return 404. Longer answer: The specification seems to provide some options regarding which status codes to use. The specification at https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.5 says:


10.4.5 404 Not Found

The server has not found anything matching the Request-URI. No indication is given of whether the condition is temporary or permanent. The 410 (Gone) status code SHOULD be used if the server knows, through some internally configurable mechanism, that an old resource is permanently unavailable and has no forwarding address. This status code is commonly used when the server does not wish to reveal exactly why the request has been refused, or when no other response is applicable.

10.4.6 405 Method Not Allowed

The method specified in the Request-Line is not allowed for the resource identified by the Request-URI. The response MUST include an Allow header containing a list of valid methods for the requested resource.


There is some room for interpretation when to use those two codes. My interpretation would be: If some resource does not exist, yet some operation conceivably could still be applied to the URI, then a 405 would be more appropriate.

For example:

GET /reservation/1

405 Method not allowed
Allow: PUT

Could mean, that although GET is not allowed on that particular resource (because it does not actually exist), you could still make PUT work, thereby creating said resource in the process.

Arguably, a 404, although allowed by the specification, would be less usable.

Regarding OPTIONS. Specification is here: https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.2 . According to specification is does not imply an interaction with the resource itself. It is more of a query to the server specifically, to determine what methods would be "theoretically" supported on the given URI. It supports for example a wildcard ("*") query, which also probably does not exist at all.

Share:
16,241
whistling_marmot
Author by

whistling_marmot

Updated on June 11, 2022

Comments

  • whistling_marmot
    whistling_marmot almost 2 years

    When a REST application receives a request for a non-existent resource, should it always return a 404 Not Found?

    Should it return a different status for any of the HTTP methods GET, HEAD, POST, PUT, DELETE, OPTIONS or TRACE?

    Spring returns a 404 for GET and HEAD, a 200 OK for OPTIONS, and a 405 Method Not Supported for the others. Is that wrong?

    e.g. This Spring Boot application shows the different responses for requests to a mis-typed URL (greetings instead of greeting).

    @RestController
    @SpringBootApplication
    public class Application {
        
        private static Logger log = LoggerFactory.getLogger(Application.class);
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
            
            RestTemplate restTemplate = new RestTemplate();
            String badUrl = "http://localhost:8080/greetings";
            for (HttpMethod httpMethod : HttpMethod.values()) {
                try {
                    restTemplate.execute(badUrl, httpMethod, null, null);
                } catch (Exception e) {
                    log.error("Failed to " + httpMethod + " -- " + e.getMessage());
                }
            }
        }
    
        @RequestMapping("/greeting")
        public String greeting() {
            return "hello";
        }
    }
    

    The logged output is:

    Failed to GET -- 404 Not Found

    Failed to HEAD -- 404 Not Found

    Failed to POST -- 405 Method Not Allowed

    Failed to PUT -- 405 Method Not Allowed

    Failed to PATCH -- I/O error on PATCH request for "http://localhost:8080/greetings": Invalid HTTP method: PATCH; nested exception is java.net.ProtocolException: Invalid HTTP method: PATCH

    Failed to DELETE -- 405 Method Not Allowed

    OPTIONS request for "http://localhost:8080/greetings" resulted in 200 (OK)

    Failed to TRACE -- 405 Method Not Allowed

  • whistling_marmot
    whistling_marmot about 8 years
    Yes, I see what you mean about GET (etc.) vs PUT. So for example, so/questionId/answerId may not exist, so we can't GET, but as long as so/questionId does exist, we can PUT - so 405 is appropriate. If the question doesn't exist, then can neither GET nor PUT an answer to it - so 404 is appropriate.
  • Robert Bräutigam
    Robert Bräutigam about 8 years
    Yes, exactly. But, again, in my reading of the error codes above there is some room for interpretation, which does or does not make sense in a particular situation. I don't think most servers or clients are ready to make such distinctions. In most situations it might not even make a difference.