# 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`**](/app-editor/page-flow/toolbox-blocks/custom-code.md) 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](/app-editor/page-flow/toolbox-blocks/custom-code.md) block.

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

## 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](/app-editor/page-flow/toolbox-blocks/custom-code.md) block.

## Web Hook Response Streaming&#x20;

[Cloud Flow Web Hooks](/app-editor/cloud-flow.md#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](/app-editor/cloud-flow/sdk-library-integration.md#axios) library. Since a `responseType` of *stream* was specified for [axios](/app-editor/cloud-flow/sdk-library-integration.md#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](/app-editor/cloud-flow/sdk-library-integration.md#axios) library. Since a `responseType` of *stream* was specified for [axios](/app-editor/cloud-flow/sdk-library-integration.md#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](/app-editor/cloud-flow/sdk-library-integration.md#csv-parser) library.&#x20;

The [csv-parser](/app-editor/cloud-flow/sdk-library-integration.md#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 %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.zingy.ai/app-editor/cloud-flow/coding-in-cloud-flow.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
