Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

like image 944
whistling_marmot Avatar asked Feb 14 '16 01:02

whistling_marmot


1 Answers

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.

like image 90
Robert Bräutigam Avatar answered Nov 15 '22 06:11

Robert Bräutigam