Streaming JSON serialization for outgoing requests
I love the optional json() feature, my HTTP code looks super tidy:
let response = self
.sheets
.reqwest
.post(url)
.json(&self.value_range)
.bearer_auth(self.sheets.oauth2_token)
.send()
.await?;
but I imagine I'm going to be streaming lots of data out this request. The code json(&T) looks like it's forcing all the data to be buffered first:
pub fn json<T: Serialize + ?Sized>(mut self, json: &T) -> RequestBuilder {
let mut error = None;
if let Ok(ref mut req) = self.request {
match serde_json::to_vec(json) {
Ok(body) => {
req.headers_mut()
.insert(CONTENT_TYPE, HeaderValue::from_static("application/json"));
*req.body_mut() = Some(body.into());
}
Err(err) => error = Some(crate::error::builder(err)),
}
}
if let Some(err) = error {
self.request = Err(err);
}
self
}
specifically serde_json::to_vec(json). Could this be converted to use serde_json::to_writer()? Maybe this is a async/blocking code problem? Looks like that's the case in serde's world: https://github.com/serde-rs/json/issues/575.
Just wanted to kick off a conversation here and have something searchable.
Streaming would need to be handled more by the user. First, you need to determine how the remote would receive it: how are the pieces streamed, is it like an array that is never closed? Or is each piece a self-contained JSON object, and they are separated by newlines?
After you've determined that, you could send a request with a channel as the body stream. Then, each time you have a part ready, you can use something like serde_json::to_vec(&item), and then push that on the channel.