Skip to content
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

Allow nonstandard HTTP methods in RestTemplate [SPR-10707] #15335

Closed
spring-projects-issues opened this issue Jun 30, 2013 · 12 comments
Closed
Labels
status: declined A suggestion or change that we don't feel we should currently apply

Comments

@spring-projects-issues
Copy link
Collaborator

M. Justin opened SPR-10707 and commented

I would like to be able to use RestTemplate with a nonstandard HTTP method that's not found in the list of 8 provided in the HttpMethod enum. Specifically, I would like to do a "PURGE" request against a Varnish cache. Such an enhancement would also allow calling other APIs with nonstandard HTTP methods, such as the various WebDAV methods.

Looking at the spring-web source code, it looks like there is currently no way of working around this while still using the library, since the HttpMethod is used exclusively throughout the code except where converted to a name to interface with the underlying HTTP library (e.g. SimpleClientHttpRequestFactory).

I would like to see a version of the exchange/execute API that takes in either an arbitrary status String, or have an interface that HttpStatus implements that could be provided in cases like this. For a concrete example of what I'm referring to (but applied to status codes rather than HTTP methods), see Status and StatusType in JAX-RS.


3 votes, 7 watchers

@spring-projects-issues
Copy link
Collaborator Author

M. Justin commented

This can be solved within Java using the HTTP Client library: http://stackoverflow.com/a/12949573/1108305. That said, it still seems like it would be good to provide a way of doing this in RestTemplate, so that multiple different APIs/configurations for the same type of thing wouldn't be needed.

@spring-projects-issues
Copy link
Collaborator Author

Phil Webb commented

I like the idea of an interface that HttpMethod could implement, however, that enum is used in quite a few places and it might be hard to make such a change without breaking backwards binary compatibility. Another issue is that the SimpleClientHttpRequestFactory only works with specific methods so to support a custom option you would need to use the the Apache HttpClient project.

Whilst not ideal, you might be able to write an new version of HttpComponentsClientHttpRequestFactory that changes one of the existing method (DELETE perhaps) to PURGE.

@spring-projects-issues
Copy link
Collaborator Author

Jiri Mikulasek commented

is there a plan for this? Once implemented it would significantly increase the range of RestTemplate's use cases.

@spring-projects-issues spring-projects-issues added status: waiting-for-triage An issue we've not yet triaged or decided on type: enhancement A general enhancement in: web Issues in web modules (web, webmvc, webflux, websocket) and removed type: enhancement A general enhancement labels Jan 11, 2019
@rstoyanchev rstoyanchev added status: bulk-closed An outdated, unresolved issue that's closed in bulk as part of a cleaning process and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Jan 11, 2019
@spring-projects-issues
Copy link
Collaborator Author

Bulk closing outdated, unresolved issues. Please, reopen if still relevant.

@mjustin
Copy link

mjustin commented Jan 22, 2019

Still relevant.

@rstoyanchev rstoyanchev reopened this Jan 22, 2019
@rstoyanchev rstoyanchev added for: team-attention type: enhancement A general enhancement and removed status: bulk-closed An outdated, unresolved issue that's closed in bulk as part of a cleaning process labels Jan 22, 2019
@rstoyanchev rstoyanchev added this to the 5.x Backlog milestone Jan 22, 2019
@rstoyanchev rstoyanchev added the status: waiting-for-triage An issue we've not yet triaged or decided on label Jan 22, 2019
@rstoyanchev
Copy link
Contributor

@mjustin could you elaborate if your use case is for the same example as in the original comment?

@rstoyanchev
Copy link
Contributor

Never mind, I just realized you are probably the original reporter ? :)

@bclozel
Copy link
Member

bclozel commented Feb 11, 2019

Hi @mjustin

The Framework team has discussed this issue in more details; here's our current understanding.

Adding support for non-standard HTTP methods, in general would mean:

  1. checking that all currently supported clients and servers are supporting that
  2. adding method variants with String and adding @Nullable where needed
  3. globally aligning the support (mapping annotations, and so on) if we want to support that properly in our programming model

While 2) and 3) are adding a complexity cost to the API and our codebase (and we can decide if it's worth it), 1) seems a bit harder since clients and servers don't seem to provide strong guarantees for that. For example, the JDK11 client will throw an IllegalArgumentException if the method name is not valid, see RFC 7230 section-3.1.1, or the method is restricted by the implementation.

On the other hand, it seems that those custom HTTP methods aren't widely supported nor mandatory to reach the same end goal. For example, the Varnish documentation mentions that you need to add specific code snippets to your configuration to support that. Moreover, looking at those configuration bits, using a specific HTTP header or any other signal in the HTTP request would work as well.

With that in mind, we're leaning on not supporting this, but we'd like to hear from you and get a better sense of how critical or widely supported is this. Also, what kind of added value RestTemplate provides for those cases instead of using an HTTP client library directly - are you expected to decode a returned response body using JSON?

Thanks!

@bclozel bclozel added the status: waiting-for-feedback We need additional information before we can continue label Feb 11, 2019
@mjustin
Copy link

mjustin commented Feb 11, 2019

Never mind, I just realized you are probably the original reporter ? :)

Correct, I was the original reporter. :-)

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Feb 11, 2019
@bclozel bclozel added status: waiting-for-feedback We need additional information before we can continue and removed status: feedback-provided Feedback has been provided labels Feb 11, 2019
@mjustin
Copy link

mjustin commented Feb 11, 2019

As alluded to in my follow-up comment on the issue, we were able to work around this by using the Apache HttpClient library. Really, the main issues with this approach were the need to pull in a second library for certain types of requests (with the need to use two separate APIs), and the need to make sure any configuration changes were applied to both libraries using their different APIs.

So it's definitely doable to do it cross-library. It's really just the matter of having to solve the same problem in different ways in the same application for operations which are both conceptually and fundamentally similar.

As for decoding the returned response body, I believe with the way things were configured we didn't really need it for our use case; the response status code of the request was enough.

As for needing to add specific code snippets to Varnish, that's true, but in order to allow purging at all you need to add some custom configuration to the Varnish configuration. Per the referenced Varnish documentation, the standard approach in Varnish is indeed to use the PURGE method.

Usually a purge is invoked through HTTP with the method PURGE.

So any alternative approaches would be deviating from the recommended Varnish standard just to support a particular Java library that's interfacing with it. Note also that Varnish isn't the only system to use the PURGE HTTP method; the Squid cache also supports it (http://etutorials.org/Server+Administration/Squid.+The+definitive+guide/Chapter+7.+Disk+Cache+Basics/7.6+Removing+Cached+Objects/).

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Feb 11, 2019
@bclozel bclozel added status: declined A suggestion or change that we don't feel we should currently apply and removed in: web Issues in web modules (web, webmvc, webflux, websocket) status: feedback-provided Feedback has been provided status: waiting-for-triage An issue we've not yet triaged or decided on type: enhancement A general enhancement labels Apr 2, 2020
@bclozel
Copy link
Member

bclozel commented Apr 2, 2020

This issue has been discussed for a while now and we've never reached a point where we could implement that in a consistent manner and where the new use cases covered would be important enough to justify the cost associated with this.

We've put RestTemplate in maintenance mode since - so we won't be adding new features nor changing its API in the future. We could consider this for WebClient, but we'd be stuck with the same problems because WebClient can be used on top of several connectors, some of them not supporting custom methods.

We advise developers to use workarounds on the server side (using other means of issuing such requests) or using a low-level HTTP client directly.
I'm closing this issue as a result.

@bclozel bclozel closed this as completed Apr 2, 2020
@mjustin
Copy link

mjustin commented Apr 2, 2020

Thanks for the thorough explanation behind the decision and the tradeoffs considered in making it. While not the most convenient situation from a usability standpoint, it is certainly understandable.

@jhoeller jhoeller removed this from the 5.x Backlog milestone Apr 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: declined A suggestion or change that we don't feel we should currently apply
Projects
None yet
Development

No branches or pull requests

5 participants