Skip to content

Return 405 Method Not Allowed for requests that do not support the http method #65

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
mmikulicz opened this issue Dec 1, 2016 · 7 comments
Assignees
Labels
Milestone

Comments

@mmikulicz
Copy link

If an endpoint only supports specific http methods (e.g. POST), and the requested method is not supported (e.g. GET), return status 405 Method Not Allowed with a message similar to The requested resource does not support http method 'GET'.

Example
Api supports: POST to \customers
Request is for: GET to \customers

Current response is 400 Bad Request

{
  "Error": {
    "$type": "system._web._http._http_error",
    "Code": "UnsupportedApiVersion",
    "Message": "The HTTP resource that matches the request URI 'http://localhost/api/v1/customers' does not support the API version '1'.",
    "InnerError": {
      "$type": "system._web._http._http_error",
      "Message": "No route providing a controller name with API version '1' was found to match request URI 'http://localhost/api/v1/customers'."
    }
  }
}

The endpoint does exist for version 1, but the method is incorrect. The current error is a bit misleading for the user.

@commonsensesoftware
Copy link
Collaborator

Currently, this is by design and the expected behavior. The rationale is that if a route could match any action for a controller, then it is treated as a possible route. If the action cannot be resolved for the requested version, then you'll get 400 because it's not supported.

While I agree that 405 is more accurate, it can be equally confusing with versioning. Imagine that GET /customers?api-version=1.0 is not supported (your example), but GET /customers?api-version=2.0 is supported. Returning 405 could be interpreted by the client as the method is not supported for any API version. Of course that may not be true and may even be discoverable via OPTIONS /customers?api-version=2.0.

This seems to be quite the gray area and I'm not sure there is a great answer. The Microsoft REST guidelines don't really call out anything specific for this scenario. In older, internal flavors of the guidelines 400 was specifically called out as the response. I don't see anything about that anymore. While I have my own opinion on the matter, my goal is to empower service authors to choose the solution that works best for them. I don't have strong feelings about not using 405.

Let me revisit the matching for actions. There is definitely complexity in sorting out matches that disambiguate between 400 and 405. The end result is still the same behavior with a slightly more informative HTTP status code. I think you should get same error code, but the message might be slightly different.

Adding a new configuration option to control the behavior would also be feasible, but I'd really like to avoid over-configuration. I'd also like see service authors fall into The Pit of Success without a whole bunch of configuration or necessary know how.

Thoughts?

@mmikulicz
Copy link
Author

The argument for using 400 makes sense. Additional code complexity & configuration options don't seem like a good solution just to add support for this.

Since 405 seems to be the default response that webapi returns, adding a note in the wiki that versioning returns a 400 for unsupported verbs would be the easiest solution.

@commonsensesoftware
Copy link
Collaborator

I think that 405 is the right way to go. Even though it might differ by version, that is the RESTFul way to go. Additionally, it has strong parity with the default behavior. Supporting 405 in this way should be queued up for the next release. I'll leave this open until then,.

@commonsensesoftware
Copy link
Collaborator

Circling back around to this - finally. After quite a bit of review, I think is actually a bug. While some strength can be given to my argument, there is nothing really mandating that 400 be used over 405. Since returning 400 instead of a 405 is a behavioral change from the original implementation, I think that is a flaw (after all). Service authors and clients should be able to work under the principle of least astonishment.

@bwurr
Copy link

bwurr commented Sep 11, 2017

A response of 405 is consistent with the REST principles. This seems to still be an issue in that 404 is being returned in .net Core. Can this be looked at again?

@commonsensesoftware
Copy link
Collaborator

405 is supported and has been for some time. The implementation is specific to API versioning however. ASP.NET Core itself still does not support 405. Design and work has been spun to address it, but it did not make it into the 2.0 release. To the best of my knowledge, it's queued for 2.1. You can track it in the ASP.NET Core repo (#6046).

The documentation for 405 support with respect to API versioning is in the wiki. Do you have a scenario or repro where this behavior is different? I think you may be experiencing an edge case that API versioning doesn't handle for 405 that should be intrinsically handled by ASP.NET Core. Since it's not, you get 404 instead of 405. I'm not sure that API versioning can or even should try to fix the systemic challenges required to make 405 work.

@bwurr
Copy link

bwurr commented Sep 12, 2017

Thanks for the reply - we just had some standard error handling tests against some of our services, and after switching to .net core experienced this issue accessing one of our services with a PUT command when it doesn't support it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants