The new async API is really helpful, thanks!
One of the problems with this API is in the documentation types like Pending (returned by reqwest::unstable::async::Client::send) and Json (returned by reqwest::unstable::asnyc::Response::json) are completely hidden so it's not possible to understand how to use these types without looking at the source. These types should be pub used properly to be able to figure the API.
I've partly liked them not being public exported, as it works similar to returning a impl Trait. The point being that the type still works, users just can't name it specifically, so reqwest doesn't need to settle on an exact name yet..
If the method that was called to receive one of these types showed an example, would that be enough to know how to use it?
as it works similar to returning a impl Trait
It's nothing like that, because we can't see what traits these types implement. Currently these functions are completely useless unless I look at the source.
If the method that was called to receive one of these types showed an example, would that be enough to know how to use it?
Probably.. Although I'd much rather see traits implemented by the type in the docs.
Just to make sure we're on the same page, here's what I see on the documentation page:

I can't click on Pending, and search bar returns nothing when I type in Pending. So there's basically no way for me to make use of the returned value.
It's nothing like that, because we can't see what traits these types implement.
I'm referring to how the code works, I realize there is an issue with the documentation. What I mean is that since it's not exported, reqwest could change the name of Pending to something else, like InFlightRequest or whatever, and that wouldn't break anyone's code, because they couldn't have used the literal name.
Just to make sure we're on the same page, here's what I see on the documentation page
Yep, same page! I'm wondering if it's possible to keep the quality of not being able to name the type, while improving the docs.
For the docs, the point about those types is that they are basically impl Future<Item=Response> and impl Future<Item=T> (where T: Deserialize). So, an "Examples" section could be added to the send method, and json, showing how it can be used. Perhaps with a link to the Future trait?
Not publicly exposing this type causes more than just document confusion - it also makes middleware-type implementations really awkward. What I mean is implementations that use reqwest to handle the HTTP(S) interactions but provide their own APIs on top of that with additional parsing, etc. So, for example, if I was trying to talking to SomeApi where I want to take an action after the Response has been received:
pub struct SomeApiFuture {
response: Pending,
}
impl Future for SomeApiFuture {
type Item = ApiResponse;
type Error = ApiError;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
let response = try_ready!(self.response.poll());
if response.status().as_u16() == 404 {
// Do something special with 404 response
} else {
// Wrap Decoder and return ApiResponse stream
}
}
}
Except I'm not able to do the above because Pending is private. That leaves me with a couple of options:
1) I can make SomeApiFuture generic like SomeApiFuture<T> with T: Future<Item = Response, Error = Error>. This has the downside of adding extra non-useful information to my type and anyone who consumes it
2) I can box the returned type as Box<Future<Item = Response, Error = Error>>. Honestly this is what I'll probably do for now, but that's a completely unnecessary allocation.
I understand not wanting to commit to an API at an early stage of development. But it's my opinion that leaving Pending private right now is doing more harm than good.
As a concrete example, somebody recently asked me to add async support to a crate I wrote, based on reqwest's async support. Since I wasn't familiar with it, I dived into the documentation, followed chain of return types from ClientBuilder → Client → RequestBuilder, found RequestBuilder::send(), and hit a dead end with Pending.
I couldn't find any code examples showing how to use this method, or any example of an asynchronous request at all. I couldn't even find a note like "this is an experimental API and shouldn't be used" or "see this blogpost for our plans for this module". As useful as async would be, I'm going to assume reqwest's async support is deliberately not ready for public consumption. Maybe there should be a big warning to that effect at the top of the reqwest::async doc comment?
@seanmonstar for reference, why are those methods not returning a plain impl Future<Item = Foo, Error = FooError>? I'm pretty confident you considered that at some point as an alternative for the private types, but I couldn't find any note on that regard.
@lucab at the time, impl Trait wasn't stable. The return types for those functions could be updated now...
@seanmonstar I can take a stab at that, if you think that's the way forward out of this. Before starting, I just wanted to cross-link https://github.com/diwic/dbus-rs/pull/165 here because it is a very similar discussion but going in the opposite direction.
Most helpful comment
Not publicly exposing this type causes more than just document confusion - it also makes middleware-type implementations really awkward. What I mean is implementations that use reqwest to handle the HTTP(S) interactions but provide their own APIs on top of that with additional parsing, etc. So, for example, if I was trying to talking to
SomeApiwhere I want to take an action after theResponsehas been received:Except I'm not able to do the above because
Pendingis private. That leaves me with a couple of options:1) I can make
SomeApiFuturegeneric likeSomeApiFuture<T>withT: Future<Item = Response, Error = Error>. This has the downside of adding extra non-useful information to my type and anyone who consumes it2) I can box the returned type as
Box<Future<Item = Response, Error = Error>>. Honestly this is what I'll probably do for now, but that's a completely unnecessary allocation.I understand not wanting to commit to an API at an early stage of development. But it's my opinion that leaving
Pendingprivate right now is doing more harm than good.