From aef53699c90801d5224f7946c7dc1f03a46b60c8 Mon Sep 17 00:00:00 2001 From: Michael Urman Date: Thu, 27 May 2021 17:02:14 -0500 Subject: [PATCH] Introduce DecodeStreamer for Client.Do This enables a client to stream values out of the HTTP response. It does so by providing a result that implements DecodeStreamer with something like the following. Error handling has been omitted for clarity. // DecodeStream decodes and processes each record of a JSON array func (streamingDecoder) DecodeStream(r io.Reader) error { dec := json.NewDecoder(r) tok, _ := dec.Token() // want: json.Delim('[') for dec.More() { _ = dec.Decode(&record) // do something with record } tok, _ = dec.Token() // want: json.Delim(']') _, err = dec.Token() // want: io.EOF return nil } --- druid.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/druid.go b/druid.go index c197c15..ed4ae1f 100644 --- a/druid.go +++ b/druid.go @@ -4,6 +4,7 @@ import ( "crypto/tls" "encoding/json" "fmt" + "io" "io/ioutil" "net/http" "net/url" @@ -133,6 +134,8 @@ func (c *Client) NewRequest(method, path string, opt interface{}) (*retryablehtt return r, nil } +type DecodeStreamer interface{ DecodeStream(io.Reader) error } + func (c *Client) Do(r *retryablehttp.Request, result interface{}) (*Response, error) { resp, err := c.http.Do(r) if err != nil { @@ -144,6 +147,9 @@ func (c *Client) Do(r *retryablehttp.Request, result interface{}) (*Response, er return nil, err } if result != nil { + if decoder, ok := result.(DecodeStreamer); ok { + return nil, decoder.DecodeStream(resp.Body) + } if err = json.NewDecoder(resp.Body).Decode(result); err != nil { return nil, err }