# Coding in Cloud Flow

{% hint style="warning" %}
For Cloud Flow,  the **`Custom Code`** block is functional in Business or higher edition apps. This block can be tested in the Standard edition.
{% endhint %}

In Cloud Flow, the [**`Custom Code`**](https://docs.zingy.ai/app-editor/page-flow/toolbox-blocks/custom-code) block allows you to add [Node.js](https://en.wikipedia.org/wiki/Node.js) based [Javascript](https://en.wikipedia.org/wiki/JavaScript) code for advanced custom functionality.

## Node.js Libraries/SDKs

Your Zingy app's server-side backend includes a curated list of Node.js SDKs and Libraries that can be used within your app's Cloud Flow Web Hooks and Background Tasks using the [Custom Code](https://docs.zingy.ai/app-editor/page-flow/toolbox-blocks/custom-code) block.

For more information about the list of integrated libraries and sdks please see [SDK/Library Integration](https://docs.zingy.ai/app-editor/cloud-flow/sdk-library-integration).

## Cloud Flow Variables and Functions

The variables and functions that are added to the Cloud Flow (using blocks) can also be referenced by the code within the [Custom Code](https://docs.zingy.ai/app-editor/page-flow/toolbox-blocks/custom-code) block.

## Web Hook Response Streaming&#x20;

[Cloud Flow Web Hooks](https://docs.zingy.ai/app-editor/cloud-flow/..#web-hook) support advanced options for sending response to the requesting client as detailed below:

### Piped (Pass-through)

When using the *Piped (Pass-through)* response streaming option, the response data needs to be provided as a [Readable stream](https://nodejs.org/docs/latest-v14.x/api/stream.html#stream_readable_streams) to the `znResponsePipe` function, the prototype for which is shown below:

```javascript
znResponsePipe(
    readable,     /* stream.Readable */
    contentType,   /* string */
    noAutoExit,    /* boolean */
    endCbFn        /* function */
)
```

<table><thead><tr><th width="165">Parameter</th><th width="160">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>readable</code></td><td><a href="https://nodejs.org/docs/latest-v14.x/api/stream.html#stream_class_stream_readable">stream.Readable</a></td><td>The stream to read from and pipe into the response</td></tr><tr><td><code>contentType</code></td><td>string</td><td>The value for the HTTP <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type">Content-Type header</a> in the response.</td></tr><tr><td><code>noAutoExit</code></td><td>boolean</td><td>By default, the <code>znResponsePipe</code> function will auto exit the Web Hook once the stream is fully read and piped. This optional parameter allows you to disable this behavior and receive a callback notification at the function specified in the <code>endCbFn</code> parameter.</td></tr><tr><td><code>endCbFn</code></td><td>function</td><td>When <code>noAutoExit</code> is set to true, this function gets called when the stream has been read or upon error. A string parameter is passed to indicate the status.</td></tr></tbody></table>

#### Example

The example below shows a large CSV file being retrieved from an external source using the [axios](https://docs.zingy.ai/app-editor/sdk-library-integration#axios) library. Since a `responseType` of *stream* was specified for [axios](https://docs.zingy.ai/app-editor/sdk-library-integration#axios), it provides a [Readable stream](https://nodejs.org/docs/latest-v14.x/api/stream.html#stream_readable_streams) at `httpResp.data` , that is passed to the `znResponsePipe` function. The `contentType` parameter is set to *text/csv*.

{% code overflow="wrap" lineNumbers="true" %}

```javascript
let axios = require('axios');
// URL of the large CSV file
let url = 'https://media.githubusercontent.com/media/datablist/sample-csv-files/main/files/customers/customers-100.csv';
axios({
    method: 'get',
    url: url,
    responseType: 'stream'
}).then(function(httpResp) {
  // Call znResponsePipe with the 
  // readable stream (httpResp.data)
  znResponsePipe(httpResp.data, 'text/csv');  
});
```

{% endcode %}

The above example conserves your Zingy app's server-side memory by directly streaming the large CSV file, instead of reading it fully and then transferring it as part of the Web Hook's response.

### Chunked

When using the *Chunked* response streaming option,  the response data is sent in batches (or chunks) to the requesting client. It sets the HTTP [Transfer-Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Transfer-Encoding) header to *chunked* in the response.

The following functions facilitate this implementation:

```javascript
znResponseChunkStart(
    contentType /* string */
)
```

The `znResponseChunkStart` function, shown above, is used to initiate the response to the client. The `contentType` parameter specifies the value for the HTTP [Content-Type header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) in the response.&#x20;

```javascript
znResponseChunkAdd(
    data /* string/binary/etc */
)
```

The  `znResponseChunkAdd` (above), is used to send the next chunk of data to the client. The `data` parameter specifies the chunk to be sent.

```javascript
znResponseChunkEnd(
    noAutoExit,    /* boolean */
    endCbFn        /* function */
)
```

The  `znResponseChunkEnd` function, shown above, is used to signal that all chunks have been sent to the client. By default, this function will auto exit the Web Hook. The `noAuthExit` parameter when set to true, prevents this and calls the function specified by the `endCbFn` parameter.

#### Example

The example below shows the same CSV file (as the Piped example above) being retrieved using the [axios](https://docs.zingy.ai/app-editor/sdk-library-integration#axios) library. Since a `responseType` of *stream* was specified for [axios](https://docs.zingy.ai/app-editor/sdk-library-integration#axios), it provides a [Readable stream](https://nodejs.org/docs/latest-v14.x/api/stream.html#stream_readable_streams) at `httpResp.data` , that is piped into the [csv-parser](https://docs.zingy.ai/app-editor/sdk-library-integration#csv-parser) library.&#x20;

The [csv-parser](https://docs.zingy.ai/app-editor/sdk-library-integration#csv-parser) library, parses the stream and produces an object for each line parsed. We are notified about this via the *data* event. In the handler for the *data* event, we convert the object to a JSON string and send as a chunk using the `znResponseChunkAdd`function.

Upon receiving the *end* event, the `znResponseChunkEnd` function is called to close the response and exit the Web Hook.

{% code overflow="wrap" lineNumbers="true" %}

```javascript
let csv = require('csv-parser');
let axios = require('axios');
// URL of the large CSV file
let url = 'https://media.githubusercontent.com/media/datablist/sample-csv-files/main/files/customers/customers-100.csv';
axios({
    method: 'get',
    url: url,
    responseType: 'stream'
}).then(function(httpResp) {
    // call znResponseChunkStart to initiate the response
    znResponseChunkStart('text/plain');
    // Pipe the httpResp.data Readable stream into 
    // the Writeable stream provided by the csv-parser
    httpResp.data.pipe(csv())
    .on('data', (obj) => {
        // convert to JSON and send chunk
        // using znResponseChunkAdd
        znResponseChunkAdd(JSON.stringify(obj)); 
    })
    .on('end', () => { 
        // call znResponseChunkEnd to signal end  
        znResponseChunkEnd(false, null);    
    });    
});

```

{% endcode %}
