github.com/josephspurrier/go-swagger@v0.2.1-0.20221129144919-1f672a142a00/examples/stream-client/README.md (about)

     1  # Streaming client
     2  
     3  This example demonstrates how to build a client from the generated client
     4  to work against a streaming server.
     5  
     6  Thanks to @nelz9999, who raised this in issue #883.
     7  
     8  
     9  This example calls `https://jigsaw.w3c.org/` so as to contentrate on the client
    10  side. For an example mixing the generated server and a client, see [here](../streaming-server/README.md).
    11  
    12  The URL called by the API returns a blob of ASCII digits (1000 lines).
    13  
    14  ## Try it
    15  
    16  ### Blocking client
    17  
    18  The client sends a request and blocks until the server has finished sending the response.
    19  
    20  ```
    21  SWAGGER_DEBUG=1 go run jigsaw.go
    22  
    23  2021/01/17 17:09:59 asking jigsaw server with blockingMode: true, chunkingMode: true
    24  GET /HTTP/ChunkedScript HTTP/1.1
    25  Host: jigsaw.w3.org
    26  User-Agent: Go-http-client/1.1
    27  Accept: application/json
    28  Accept-Encoding: gzip
    29  
    30  
    31  HTTP/1.1 200 OK
    32  Transfer-Encoding: chunked
    33  Cache-Control: max-age=0
    34  Content-Type: text/plain
    35  ...
    36  Server: Jigsaw/2.3.0-beta2
    37  Strict-Transport-Security: max-age=15552015; includeSubDomains; preload
    38  X-Frame-Options: deny
    39  X-Xss-Protection: 1; mode=block
    40  
    41  2021/01/17 17:10:00 result: This output will be chunked encoded by the server, if your client is HTTP/1.1
    42  Below this line, is 1000 repeated lines of 0-9.
    43  -------------------------------------------------------------------------
    44  01234567890123456789012345678901234567890123456789012345678901234567890
    45  ...
    46  01234567890123456789012345678901234567890123456789012345678901234567890
    47  ```
    48  
    49  ```
    50  # http2 client is detected by jigsaw: response is not chunked
    51  SWAGGER_DEBUG=1 go run jigsaw.go nochunking
    52  
    53  2021/01/17 17:10:12 asking jigsaw server with blockingMode: true, chunkingMode: false
    54  GET /HTTP/ChunkedScript HTTP/1.1
    55  Host: jigsaw.w3.org
    56  User-Agent: Go-http-client/1.1
    57  Accept: application/json
    58  Accept-Encoding: gzip
    59  
    60  
    61  HTTP/2.0 200 OK
    62  Connection: close
    63  Cache-Control: max-age=0
    64  Content-Type: text/plain
    65  ...
    66  Server: Jigsaw/2.3.0-beta3
    67  Strict-Transport-Security: max-age=15552015; includeSubDomains; preload
    68  X-Frame-Options: deny
    69  X-Xss-Protection: 1; mode=block
    70  ...
    71  
    72  2021/01/17 17:10:12 result: This output will be chunked encoded by the server, if your client is HTTP/1.1
    73  Below this line, is 1000 repeated lines of 0-9.
    74  -------------------------------------------------------------------------
    75  01234567890123456789012345678901234567890123456789012345678901234567890
    76  ...
    77  01234567890123456789012345678901234567890123456789012345678901234567890
    78  ```
    79  
    80  ### Non-blocking client
    81  
    82  The client sends a request and consumes the chunks as they are produced.
    83  
    84  ```
    85  SWAGGER_DEBUG=1 go run jigsaw.go nonblocking
    86  
    87  2021/01/17 17:09:23 asking jigsaw server with blockingMode: false, chunkingMode: true
    88  GET /HTTP/ChunkedScript HTTP/1.1
    89  Host: jigsaw.w3.org
    90  User-Agent: Go-http-client/1.1
    91  Accept: application/json
    92  Accept-Encoding: gzip
    93  
    94  HTTP/1.1 200 OK
    95  Transfer-Encoding: chunked
    96  Cache-Control: max-age=0
    97  Content-Type: text/plain
    98  ...
    99  Server: Jigsaw/2.3.0-beta4
   100  Strict-Transport-Security: max-age=15552015; includeSubDomains; preload
   101  X-Frame-Options: deny
   102  X-Xss-Protection: 1; mode=block
   103  
   104  2021/01/17 17:09:23 line[1]: This output will be chunked encoded by the server, if your client is HTTP/1.1
   105  2021/01/17 17:09:23 line[2]: Below this line, is 1000 repeated lines of 0-9.
   106  2021/01/17 17:09:23 line[3]: -------------------------------------------------------------------------
   107  2021/01/17 17:09:23 line[4]: 01234567890123456789012345678901234567890123456789012345678901234567890
   108  2021/01/17 17:09:23 line[5]: 01234567890123456789012345678901234567890123456789012345678901234567890
   109  ...
   110  2021/01/17 17:09:23 line[1003]: 01234567890123456789012345678901234567890123456789012345678901234567890
   111  2021/01/17 17:09:23 EOF
   112  ```
   113  
   114  ```
   115  SWAGGER_DEBUG=1 go run jigsaw.go nonblocking nochunking
   116  
   117  2021/01/17 17:09:39 asking jigsaw server with blockingMode: false, chunkingMode: false
   118  GET /HTTP/ChunkedScript HTTP/1.1
   119  Host: jigsaw.w3.org
   120  User-Agent: Go-http-client/1.1
   121  Accept: application/json
   122  Accept-Encoding: gzip
   123  
   124  HTTP/2.0 200 OK
   125  Connection: close
   126  Cache-Control: max-age=0
   127  Content-Type: text/plain
   128  ...
   129  Server: Jigsaw/2.3.0-beta3
   130  Strict-Transport-Security: max-age=15552015; includeSubDomains; preload
   131  X-Frame-Options: deny
   132  X-Xss-Protection: 1; mode=block
   133  
   134  2021/01/17 17:09:39 line[1]: This output will be chunked encoded by the server, if your client is HTTP/1.1
   135  2021/01/17 17:09:39 line[2]: Below this line, is 1000 repeated lines of 0-9.
   136  2021/01/17 17:09:39 line[3]: -------------------------------------------------------------------------
   137  2021/01/17 17:09:39 line[4]: 01234567890123456789012345678901234567890123456789012345678901234567890
   138  2021/01/17 17:09:39 line[5]: 01234567890123456789012345678901234567890123456789012345678901234567890
   139  ...
   140  2021/01/17 17:09:39 line[1002]: 01234567890123456789012345678901234567890123456789012345678901234567890
   141  2021/01/17 17:09:39 line[1003]: 01234567890123456789012345678901234567890123456789012345678901234567890
   142  2021/01/17 17:09:39 EOF
   143  ```
   144  
   145  ## How does it work?
   146  
   147  ### Blocking: customizing the `io.Writer`
   148  
   149  We have specified a `binary` format for the response (instead of, say, `[]string`).
   150  
   151  We need to provide the runtime consumer with some means to unmarshal `text/plain` in this buffer.
   152  
   153  The simplest way is to equip the destination buffer with a `UnmarshalText()` method. Like so:
   154  ```go
   155  type Buffer struct {
   156  	*bytes.Buffer
   157  }
   158  
   159  // UnmarshalText handles text/plain
   160  func (b *Buffer) UnmarshalText(text []byte) error {
   161  	_, err := b.Write(text)
   162  	return err
   163  }
   164  
   165  buf := NewBuffer()
   166  _, err := c.Chunked(operations.NewChunkedParams(), buf)
   167  ```
   168  
   169  ### Non-blocking: customizing the consumer
   170  
   171  We need to instruct the runtime client to use a `ByteStreamConsumer` when the response is `text/plain`.
   172  Like so:
   173  
   174  ```go
   175  	transport.Consumers[runtime.TextMime] = runtime.ByteStreamConsumer()
   176  ```
   177  
   178  #### Non-blocking: unmarshalling the stream
   179  
   180  The response is just a stream of byte, so the client has to unmarshal the messages received unitarily.
   181  In this example, the stream is separated by line feed, so we can use a `bufio.Scanner` to do the job.
   182  
   183  Notice the use of the `cancel()` method to interrupt the ongoing request if the go routine fails.