You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@hc.apache.org by Oleg Kalnichevski <ol...@apache.org> on 2021/11/08 09:29:12 UTC

Deprecation of CloseableHttpResponse in HttpClient 5.2?

Folks

Now that HttpClient 5.2 runs I would like to deprecate a decade old way 
of handling responses in favor of HttpClientResponseHandler functional 
interface approach:


This common pattern should be discouraged going forward
```
try (final CloseableHttpResponse response = httpclient.execute(httppost)) {
     System.out.println("----------------------------------------");
     System.out.println(response.getCode() + " " + 
response.getReasonPhrase());
     System.out.println(EntityUtils.toString(response.getEntity()));
}
```
and be replaced by this one:

```
httpclient.execute(httppost, response -> {
     System.out.println("----------------------------------------");
     System.out.println(response.getCode() + " " + 
response.getReasonPhrase());
     System.out.println(EntityUtils.toString(response.getEntity()));
     return null;
});
```

There are several advantages to the functional interface based approach:

1. it eliminates the entire class of resource leaks due sloppy exception 
handling in the application code.

2. it would make it easier to implement a classic i/o compatibility 
layer on top of the async APIs should we ever decide to build such a thing.

On the downside some users might not like the fact that they would need 
to adjust their existing HTTP response handling logic, but that is the 
case with all new things.

Please let me know what you think.

Oleg

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org


Re: Deprecation of CloseableHttpResponse in HttpClient 5.2?

Posted by Oleg Kalnichevski <ol...@apache.org>.

On 11/10/2021 9:18 PM, Gary Gregory wrote:
> If we are still going to support the old style API because we still need it
> as an escape hatch to implement complex solutions, those APIs should not
> become deprecated IMO.
> 

I think we can conclude the old classic API based on 
CloseableHttpResponse cannot be deprecated.

Oleg

> Gary
> 
> On Tue, Nov 9, 2021, 14:01 Oleg Kalnichevski <ol...@apache.org> wrote:
> 
>>
>>
>> On 11/9/2021 10:07 AM, Michael Osipov wrote:
>>> Am 2021-11-08 um 17:52 schrieb Oleg Kalnichevski:
>>>>
>>>>
>>>> On 11/8/2021 5:03 PM, Michael Osipov wrote:
>>>>> Am 2021-11-08 um 16:56 schrieb Oleg Kalnichevski:
>>>>>>
>>>>
>>>> ...
>>>>
>>>>> I need to setup a small project next week. Give me a bit of time.
>>>>> The above won't work because DataHandler is
>>>>> javax.activation.DataHandler used with SOAP MTOM directly in the
>>>>> generated clients. I see no way to return that input stream with a
>>>>> closure because it contrdicts the closure concept.
>>>>> I don't know how familiar you are with JAX-WS and MTOM, but those
>>>>> DataHandlers are core concepts with are passed around with a readable
>>>>> source either as input or output.
>>>>> See also
>>>>>
>> https://docs.oracle.com/middleware/1212/wls/WSGET/jax-ws-mtom.htm#WSGET3485.
>>
>>>>>
>>>>>
>>>>> As of now, I am afraid that a closure will not be able to cover all
>>>>> possible usecases.
>>>>>
>>>>> Michael
>>>>>
>>>>
>>>> I must recant my previous statement. Not everything can be turned into
>>>> a closure without some (sometimes major) refactoring, and some APIs
>>>> are just given and cannot be refactored.
>>>
>>> Does this mean that deprecating it does not work out at the end and it
>>> has to remain as an alternative?
>>
>> Yes, it does. We will have to keep supporting CloseableHttpResponse.
>>
>> Oleg
>>
>>>
>>>> Still I want to put more emphasis on the usage of
>>>> HttpClientResponseHandler going forward and steer users toward using
>>>> it as closures in their application code. Starting with our sample
>>>> code and the migration guide.
>>>
>>>
>>> I agree that we should favorize the closure since it is less headache.
>>>
>>> M
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
>>> For additional commands, e-mail: dev-help@hc.apache.org
>>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
>> For additional commands, e-mail: dev-help@hc.apache.org
>>
>>
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org


Re: Deprecation of CloseableHttpResponse in HttpClient 5.2?

Posted by Gary Gregory <ga...@gmail.com>.
If we are still going to support the old style API because we still need it
as an escape hatch to implement complex solutions, those APIs should not
become deprecated IMO.

Gary

On Tue, Nov 9, 2021, 14:01 Oleg Kalnichevski <ol...@apache.org> wrote:

>
>
> On 11/9/2021 10:07 AM, Michael Osipov wrote:
> > Am 2021-11-08 um 17:52 schrieb Oleg Kalnichevski:
> >>
> >>
> >> On 11/8/2021 5:03 PM, Michael Osipov wrote:
> >>> Am 2021-11-08 um 16:56 schrieb Oleg Kalnichevski:
> >>>>
> >>
> >> ...
> >>
> >>> I need to setup a small project next week. Give me a bit of time.
> >>> The above won't work because DataHandler is
> >>> javax.activation.DataHandler used with SOAP MTOM directly in the
> >>> generated clients. I see no way to return that input stream with a
> >>> closure because it contrdicts the closure concept.
> >>> I don't know how familiar you are with JAX-WS and MTOM, but those
> >>> DataHandlers are core concepts with are passed around with a readable
> >>> source either as input or output.
> >>> See also
> >>>
> https://docs.oracle.com/middleware/1212/wls/WSGET/jax-ws-mtom.htm#WSGET3485.
>
> >>>
> >>>
> >>> As of now, I am afraid that a closure will not be able to cover all
> >>> possible usecases.
> >>>
> >>> Michael
> >>>
> >>
> >> I must recant my previous statement. Not everything can be turned into
> >> a closure without some (sometimes major) refactoring, and some APIs
> >> are just given and cannot be refactored.
> >
> > Does this mean that deprecating it does not work out at the end and it
> > has to remain as an alternative?
>
> Yes, it does. We will have to keep supporting CloseableHttpResponse.
>
> Oleg
>
> >
> >> Still I want to put more emphasis on the usage of
> >> HttpClientResponseHandler going forward and steer users toward using
> >> it as closures in their application code. Starting with our sample
> >> code and the migration guide.
> >
> >
> > I agree that we should favorize the closure since it is less headache.
> >
> > M
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
> > For additional commands, e-mail: dev-help@hc.apache.org
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
> For additional commands, e-mail: dev-help@hc.apache.org
>
>

Re: Deprecation of CloseableHttpResponse in HttpClient 5.2?

Posted by Oleg Kalnichevski <ol...@apache.org>.

On 11/9/2021 10:07 AM, Michael Osipov wrote:
> Am 2021-11-08 um 17:52 schrieb Oleg Kalnichevski:
>>
>>
>> On 11/8/2021 5:03 PM, Michael Osipov wrote:
>>> Am 2021-11-08 um 16:56 schrieb Oleg Kalnichevski:
>>>>
>>
>> ...
>>
>>> I need to setup a small project next week. Give me a bit of time.
>>> The above won't work because DataHandler is 
>>> javax.activation.DataHandler used with SOAP MTOM directly in the 
>>> generated clients. I see no way to return that input stream with a 
>>> closure because it contrdicts the closure concept.
>>> I don't know how familiar you are with JAX-WS and MTOM, but those 
>>> DataHandlers are core concepts with are passed around with a readable 
>>> source either as input or output.
>>> See also 
>>> https://docs.oracle.com/middleware/1212/wls/WSGET/jax-ws-mtom.htm#WSGET3485. 
>>>
>>>
>>> As of now, I am afraid that a closure will not be able to cover all 
>>> possible usecases.
>>>
>>> Michael
>>>
>>
>> I must recant my previous statement. Not everything can be turned into 
>> a closure without some (sometimes major) refactoring, and some APIs 
>> are just given and cannot be refactored.
> 
> Does this mean that deprecating it does not work out at the end and it 
> has to remain as an alternative?

Yes, it does. We will have to keep supporting CloseableHttpResponse.

Oleg

> 
>> Still I want to put more emphasis on the usage of 
>> HttpClientResponseHandler going forward and steer users toward using 
>> it as closures in their application code. Starting with our sample 
>> code and the migration guide.
> 
> 
> I agree that we should favorize the closure since it is less headache.
> 
> M
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
> For additional commands, e-mail: dev-help@hc.apache.org
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org


Re: Deprecation of CloseableHttpResponse in HttpClient 5.2?

Posted by Michael Osipov <mi...@apache.org>.
Am 2021-11-08 um 17:52 schrieb Oleg Kalnichevski:
> 
> 
> On 11/8/2021 5:03 PM, Michael Osipov wrote:
>> Am 2021-11-08 um 16:56 schrieb Oleg Kalnichevski:
>>>
> 
> ...
> 
>> I need to setup a small project next week. Give me a bit of time.
>> The above won't work because DataHandler is 
>> javax.activation.DataHandler used with SOAP MTOM directly in the 
>> generated clients. I see no way to return that input stream with a 
>> closure because it contrdicts the closure concept.
>> I don't know how familiar you are with JAX-WS and MTOM, but those 
>> DataHandlers are core concepts with are passed around with a readable 
>> source either as input or output.
>> See also 
>> https://docs.oracle.com/middleware/1212/wls/WSGET/jax-ws-mtom.htm#WSGET3485. 
>>
>>
>> As of now, I am afraid that a closure will not be able to cover all 
>> possible usecases.
>>
>> Michael
>>
> 
> I must recant my previous statement. Not everything can be turned into a 
> closure without some (sometimes major) refactoring, and some APIs are 
> just given and cannot be refactored.

Does this mean that deprecating it does not work out at the end and it 
has to remain as an alternative?

> Still I want to put more emphasis on the usage of 
> HttpClientResponseHandler going forward and steer users toward using it 
> as closures in their application code. Starting with our sample code and 
> the migration guide.


I agree that we should favorize the closure since it is less headache.

M

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org


Re: Deprecation of CloseableHttpResponse in HttpClient 5.2?

Posted by Oleg Kalnichevski <ol...@apache.org>.

On 11/8/2021 5:03 PM, Michael Osipov wrote:
> Am 2021-11-08 um 16:56 schrieb Oleg Kalnichevski:
>>

...

> I need to setup a small project next week. Give me a bit of time.
> The above won't work because DataHandler is javax.activation.DataHandler 
> used with SOAP MTOM directly in the generated clients. I see no way to 
> return that input stream with a closure because it contrdicts the 
> closure concept.
> I don't know how familiar you are with JAX-WS and MTOM, but those 
> DataHandlers are core concepts with are passed around with a readable 
> source either as input or output.
> See also 
> https://docs.oracle.com/middleware/1212/wls/WSGET/jax-ws-mtom.htm#WSGET3485. 
> 
> 
> As of now, I am afraid that a closure will not be able to cover all 
> possible usecases.
> 
> Michael
> 

I must recant my previous statement. Not everything can be turned into a 
closure without some (sometimes major) refactoring, and some APIs are 
just given and cannot be refactored.

Still I want to put more emphasis on the usage of 
HttpClientResponseHandler going forward and steer users toward using it 
as closures in their application code. Starting with our sample code and 
the migration guide.

Oleg

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org


Re: Deprecation of CloseableHttpResponse in HttpClient 5.2?

Posted by Michael Osipov <mi...@apache.org>.
Am 2021-11-08 um 16:56 schrieb Oleg Kalnichevski:
> 
> 
> On 11/8/2021 4:26 PM, Michael Osipov wrote:
>> Well, that is going to be a problem because the code in the low level
>> method looks like this:
>> 
>>> CloseableHttpResponse downloadResponse = httpClient.execute(downloadFile);
>>> 
>>> DataHandler dh = new DataHandler(new InputStreamDataSource(new
>>> HttpResponseInputStream(
>>>         downloadResponse)));
>> 
>> dh is passed on to the return object and a high level class is processing
>> the response implicitly. I don't see way to make that work in a closure.
>> 
> 
> Something like that. Give me a compilable code and will put the handling
> logic into a closure.
> 
> ```
> Object result = httpclient.execute(downloadFile, response -> {
>      DataHandler dh = new DataHandler(new InputStreamDataSource(new
> HttpResponseInputStream(response)));
>      return dh.handle();
> });
> ```


I need to setup a small project next week. Give me a bit of time.
The above won't work because DataHandler is javax.activation.DataHandler used
with SOAP MTOM directly in the generated clients. I see no way to return that
input stream with a closure because it contrdicts the closure concept.
I don't know how familiar you are with JAX-WS and MTOM, but those DataHandlers
are core concepts with are passed around with a readable source either as
input or output.
See also https://docs.oracle.com/middleware/1212/wls/WSGET/jax-ws-
mtom.htm#WSGET3485.

As of now, I am afraid that a closure will not be able to cover all possible
usecases.

Michael

Re: Deprecation of CloseableHttpResponse in HttpClient 5.2?

Posted by Oleg Kalnichevski <ol...@apache.org>.

On 11/8/2021 4:26 PM, Michael Osipov wrote:
> Well, that is going to be a problem because the code in the low level 
> method looks like this:
> 
>> CloseableHttpResponse downloadResponse = 
>> httpClient.execute(downloadFile);
>>
>> DataHandler dh = new DataHandler(new InputStreamDataSource(new 
>> HttpResponseInputStream(
>>         downloadResponse)));
> 
> dh is passed on to the return object and a high level class is 
> processing the response implicitly. I don't see way to make that work in 
> a closure.
>

Something like that. Give me a compilable code and will put the handling 
logic into a closure.

```
Object result = httpclient.execute(downloadFile, response -> {
     DataHandler dh = new DataHandler(new InputStreamDataSource(new 
HttpResponseInputStream(response)));
     return dh.handle();
});
```

Oleg

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org


Re: Deprecation of CloseableHttpResponse in HttpClient 5.2?

Posted by Michael Osipov <mi...@apache.org>.
Am 2021-11-08 um 15:00 schrieb Oleg Kalnichevski:
> 
> 
> On 11/8/2021 2:47 PM, Michael Osipov wrote:
>> Am 2021-11-08 um 10:29 schrieb Oleg Kalnichevski:
>>> Folks
>>> 
>>> Now that HttpClient 5.2 runs I would like to deprecate a decade old way of
>>> handling responses in favor of HttpClientResponseHandler functional
>>> interface approach:
>>> 
>>> 
>>> This common pattern should be discouraged going forward
>>> ```
>>> try (final CloseableHttpResponse response = httpclient.execute(httppost))
>>> {
>>>      System.out.println("----------------------------------------");
>>>      System.out.println(response.getCode() + " " +
>>> response.getReasonPhrase());
>>>      System.out.println(EntityUtils.toString(response.getEntity()));
>>> }
>>> ```
>>> and be replaced by this one:
>>> 
>>> ```
>>> httpclient.execute(httppost, response -> {
>>>      System.out.println("----------------------------------------");
>>>      System.out.println(response.getCode() + " " +
>>> response.getReasonPhrase());
>>>      System.out.println(EntityUtils.toString(response.getEntity()));
>>>      return null;
>>> });
>>> ```
>>> 
>>> There are several advantages to the functional interface based approach:
>>> 
>>> 1. it eliminates the entire class of resource leaks due sloppy exception
>>> handling in the application code.
>>> 
>>> 2. it would make it easier to implement a classic i/o compatibility layer
>>> on top of the async APIs should we ever decide to build such a thing.
>>> 
>>> On the downside some users might not like the fact that they would need to
>>> adjust their existing HTTP response handling logic, but that is the case
>>> with all new things.
>>> 
>>> Please let me know what you think.
>> 
>> Generally, I think this is a good move for most cases, but how these
>> cases/questions you be handled:
>> * Do I need to return the entire consumed input stream?
> 
> One should consume the response message stream inside the handler and return
> it back to the caller as a higher level domain object
> 
> https://github.com/apache/httpcomponents-client/blob/4.5.x/httpclient/src/ex
> amples/org/apache/http/examples/client/ClientWithResponseHandler.java
> 
> This is the same pattern we have been advocating since early days of 4.x.
> With lambdas it just looks cleaner.
> 
> 
>> * How is an external consumer supposed to receive the response and stream
>> in in some fashion?
>> 
>> I have a very explicit usecase which has been working for me and I don't
>> know whether it will continue to work:
>> 
>> ===> client (via SOAP or REST GET)  ===> Tomcat, issue GET to upstream =>
>> file from response streamed => client
>> 
>> In this case my code in Tomcat acts like a reverse proxy with a lot of
>> custom logic and the CloseableHttpResponse is passed as as I SOAP
>> DataSource/DataHandler and JAX-WS Metro/JAX-RS Jersey do the rest.
>> 
> 
> Not much different, just your code gets executed inside a closure and no
> longer needs to explicitly close the response object.

Well, that is going to be a problem because the code in the low level method
looks like this:

> CloseableHttpResponse downloadResponse = httpClient.execute(downloadFile);
> 
> DataHandler dh = new DataHandler(new InputStreamDataSource(new HttpResponseInputStream(
> 		downloadResponse)));

dh is passed on to the return object and a high level class is processing the
response implicitly. I don't see way to make that work in a closure.

M

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org


Re: Deprecation of CloseableHttpResponse in HttpClient 5.2?

Posted by Oleg Kalnichevski <ol...@apache.org>.

On 11/8/2021 2:47 PM, Michael Osipov wrote:
> Am 2021-11-08 um 10:29 schrieb Oleg Kalnichevski:
>> Folks
>>
>> Now that HttpClient 5.2 runs I would like to deprecate a decade old 
>> way of handling responses in favor of HttpClientResponseHandler 
>> functional interface approach:
>>
>>
>> This common pattern should be discouraged going forward
>> ```
>> try (final CloseableHttpResponse response = 
>> httpclient.execute(httppost)) {
>>      System.out.println("----------------------------------------");
>>      System.out.println(response.getCode() + " " + 
>> response.getReasonPhrase());
>>      System.out.println(EntityUtils.toString(response.getEntity()));
>> }
>> ```
>> and be replaced by this one:
>>
>> ```
>> httpclient.execute(httppost, response -> {
>>      System.out.println("----------------------------------------");
>>      System.out.println(response.getCode() + " " + 
>> response.getReasonPhrase());
>>      System.out.println(EntityUtils.toString(response.getEntity()));
>>      return null;
>> });
>> ```
>>
>> There are several advantages to the functional interface based approach:
>>
>> 1. it eliminates the entire class of resource leaks due sloppy 
>> exception handling in the application code.
>>
>> 2. it would make it easier to implement a classic i/o compatibility 
>> layer on top of the async APIs should we ever decide to build such a 
>> thing.
>>
>> On the downside some users might not like the fact that they would 
>> need to adjust their existing HTTP response handling logic, but that 
>> is the case with all new things.
>>
>> Please let me know what you think.
> 
> Generally, I think this is a good move for most cases, but how these 
> cases/questions you be handled:
> * Do I need to return the entire consumed input stream?

One should consume the response message stream inside the handler and 
return it back to the caller as a higher level domain object

https://github.com/apache/httpcomponents-client/blob/4.5.x/httpclient/src/examples/org/apache/http/examples/client/ClientWithResponseHandler.java

This is the same pattern we have been advocating since early days of 
4.x. With lambdas it just looks cleaner.


> * How is an external consumer supposed to receive the response and 
> stream in in some fashion?
> 
> I have a very explicit usecase which has been working for me and I don't 
> know whether it will continue to work:
> 
> ===> client (via SOAP or REST GET)  ===> Tomcat, issue GET to upstream 
> => file from response streamed => client
> 
> In this case my code in Tomcat acts like a reverse proxy with a lot of 
> custom logic and the CloseableHttpResponse is passed as as I SOAP 
> DataSource/DataHandler and JAX-WS Metro/JAX-RS Jersey do the rest.
> 

Not much different, just your code gets executed inside a closure and no 
longer needs to explicitly close the response object.

Think of it as Spring Template callbacks.

Oleg

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org


Re: Deprecation of CloseableHttpResponse in HttpClient 5.2?

Posted by Michael Osipov <mi...@apache.org>.
Am 2021-11-08 um 10:29 schrieb Oleg Kalnichevski:
> Folks
> 
> Now that HttpClient 5.2 runs I would like to deprecate a decade old way of
> handling responses in favor of HttpClientResponseHandler functional
> interface approach:
> 
> 
> This common pattern should be discouraged going forward
> ```
> try (final CloseableHttpResponse response = httpclient.execute(httppost)) {
>      System.out.println("----------------------------------------");
>      System.out.println(response.getCode() + " " +
> response.getReasonPhrase());
>      System.out.println(EntityUtils.toString(response.getEntity()));
> }
> ```
> and be replaced by this one:
> 
> ```
> httpclient.execute(httppost, response -> {
>      System.out.println("----------------------------------------");
>      System.out.println(response.getCode() + " " +
> response.getReasonPhrase());
>      System.out.println(EntityUtils.toString(response.getEntity()));
>      return null;
> });
> ```
> 
> There are several advantages to the functional interface based approach:
> 
> 1. it eliminates the entire class of resource leaks due sloppy exception
> handling in the application code.
> 
> 2. it would make it easier to implement a classic i/o compatibility layer on
> top of the async APIs should we ever decide to build such a thing.
> 
> On the downside some users might not like the fact that they would need to
> adjust their existing HTTP response handling logic, but that is the case
> with all new things.
> 
> Please let me know what you think.

Generally, I think this is a good move for most cases, but how these
cases/questions you be handled:
* Do I need to return the entire consumed input stream?
* How is an external consumer supposed to receive the response and stream in
in some fashion?

I have a very explicit usecase which has been working for me and I don't know
whether it will continue to work:

===> client (via SOAP or REST GET)  ===> Tomcat, issue GET to upstream => file
from response streamed => client

In this case my code in Tomcat acts like a reverse proxy with a lot of custom
logic and the CloseableHttpResponse is passed as as I SOAP
DataSource/DataHandler and JAX-WS Metro/JAX-RS Jersey do the rest.

Michael