Skip to content

Commit bd07768

Browse files
authored
Merge pull request #45 from FlutterFlow/pooja/actions
Function > Actions + Concepts
2 parents de2b71e + 74d275d commit bd07768

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+2980
-1
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"label": "Control Flow & Logic",
3+
"position": 3
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"label": "Backend Logic",
3+
"position": 3
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"label": "API Calls",
3+
"position": 1
4+
}

docs/resources/control-flow/backend-logic/api/api-calls-101.md

Lines changed: 717 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 359 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,359 @@
1+
---
2+
title: Streaming APIs
3+
---
4+
5+
6+
# Streaming API Example: AI Review Summary
7+
8+
Streaming APIs provide a continuous flow of data over a long-lived HTTP connection, enabling real-time updates for your application.
9+
10+
Unlike REST APIs, which deliver data in response to specific requests, streaming APIs are designed to maintain an open connection between the client and the server, continuously sending data as it becomes available. This is particularly useful for applications that require live updates, such as live sports scores, stock market tickers, chat applications, and real-time notifications.
11+
12+
This reduces latency and improves the user experience by providing immediate feedback. The most common protocol used for streaming APIs is Server Sent Events (SSE), but others like WebSockets can also be used depending on the application's requirements.
13+
14+
### Difference between REST APIs and Streaming APIs
15+
16+
The primary difference between REST APIs and Streaming APIs lies in their data delivery methods:
17+
18+
* **REST APIs**:
19+
+ **Request/Response Model**: The client sends a request, and the server responds with the data.
20+
+ **Connection Lifecycle**: Each request/response pair is independent, and the server closes the connection after sending the response.
21+
+ **Use Case**: Suitable for applications where data doesn't change frequently and real-time updates aren't critical.
22+
+ **Example response**:
23+
24+
```
25+
{
26+
"event": "match_score",
27+
"data": {
28+
"team1": "Red Dragons",
29+
"team2": "Silver Sharks",
30+
"score": "2-1"
31+
}
32+
}
33+
```
34+
* **Streaming APIs (Server Sent Events)**:
35+
+ **Continuous Data Stream**: The server maintains an open connection and continuously sends data to the client as it becomes available.
36+
+ **Connection Lifecycle**: The connection remains open, allowing the server to push new data to the client without the client having to request it.
37+
+ **Use Case**: Ideal for applications requiring real-time updates, such as live sports scores, real-time notifications, and live chat applications.
38+
+ **Example response**:
39+
40+
```
41+
event: match_score
42+
data: {"team1": "Red Dragons", "team2": "Silver Sharks", "score": "2-1"}
43+
44+
event: match_score
45+
data: {"team1": "Red Dragons", "team2": "Silver Sharks", "score": "3-1"}
46+
47+
event: match_score
48+
data: {"team1": "Red Dragons", "team2": "Silver Sharks", "score": "3-2"}
49+
```
50+
51+
## Building an App
52+
53+
Let's see how you can use streaming APIs in FlutterFlow by building an example that allows users to see an AI summary of product reviews. On page load, the app displays the AI summary in real-time, letting users watch the analysis unfold as it's being generated.
54+
55+
The final app looks like this:
56+
57+
<div style={{
58+
position: 'relative',
59+
paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding
60+
height: 0,
61+
width: '100%'
62+
}}>
63+
<iframe
64+
src="https://demo.arcade.software/EPHAltGtmoefX2QTXb0H?embed&show_copy_link=true"
65+
title=""
66+
style={{
67+
position: 'absolute',
68+
top: 0,
69+
left: 0,
70+
width: '100%',
71+
height: '100%',
72+
colorScheme: 'light'
73+
}}
74+
frameborder="0"
75+
loading="lazy"
76+
webkitAllowFullScreen
77+
mozAllowFullScreen
78+
allowFullScreen
79+
allow="clipboard-write">
80+
</iframe>
81+
</div>
82+
83+
<p></p>
84+
85+
The steps to build the app are as follows:
86+
87+
1. [Build UI](/data-and-backend/api-calls/streaming-api-example-ai-review-summary#id-1.-build-ui)
88+
5. [Create API](/data-and-backend/api-calls/streaming-api-example-ai-review-summary#id-2.-create-api)
89+
8. [Create page state variable](/data-and-backend/api-calls/streaming-api-example-ai-review-summary#id-3.-create-page-state-variable)
90+
11. [Trigger and Parse API response](/data-and-backend/api-calls/streaming-api-example-ai-review-summary#id-4.-trigger-and-extract-data-from-api-response)
91+
14. [Extract chart data](/data-and-backend/api-calls/streaming-api-example-ai-review-summary#id-5.-extract-chart-data)
92+
93+
### 1. Build UI
94+
95+
The user interface includes a section for the average rating, and number of reviews, followed by a detailed summary of the reviews including pros, cons, and sentiment distribution visualization. Here are key widgets to build the page:
96+
97+
* [**Text Widget**](/widgets-and-components/widgets/base-elements/text): Displays the AI-generated summary of the reviews and a list of the positive and negative points mentioned in the reviews.
98+
* [**Chart (Bar chart) Widget**](/widgets-and-components/widgets/base-elements/chart/bar-chart): Visual representation of the sentiment distribution (positive, neutral, negative) in a bar chart.
99+
![streaming-api-example-demo.png](..%2Fimgs%2Fstreaming-api-example-demo.png)
100+
101+
### 2. Create API
102+
103+
For building this app, we will use [OpenAI's Chat Completion API](https://platform.openai.com/docs/guides/text-generation/chat-completions-api) to generate a summary based on given reviews. Before you build anything related to APIs in your app, it's essential to create and test the APIs to ensure they work correctly. So let's [create and test](/data-and-backend/api-calls/create-and-test-api-call) the Chat Completion API in our project.
104+
105+
Once created, open the **Advanced Settings** and **enable** the **Process Stream Response** toggle.
106+
107+
Here's how you do it:
108+
109+
<div style={{
110+
position: 'relative',
111+
paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding
112+
height: 0,
113+
width: '100%'
114+
}}>
115+
<iframe
116+
src="https://demo.arcade.software/erzDAcLQ1mR7coF28oFi?embed&show_copy_link=true"
117+
title=""
118+
style={{
119+
position: 'absolute',
120+
top: 0,
121+
left: 0,
122+
width: '100%',
123+
height: '100%',
124+
colorScheme: 'light'
125+
}}
126+
frameborder="0"
127+
loading="lazy"
128+
webkitAllowFullScreen
129+
mozAllowFullScreen
130+
allowFullScreen
131+
allow="clipboard-write">
132+
</iframe>
133+
</div>
134+
135+
136+
137+
### 3. Create page state variables
138+
139+
In this example, to hold and display the result of the generated AI summary, you'll need two variables.
140+
141+
2. `summary`: This variable will hold the full text of the summary that includes the overall sentiment of the reviews, key points mentioned by customers, and lists of pros and cons. It is initialized as an empty string and will later be updated with the AI-generated text.
142+
5. `sentimentValues`: This variable will store the sentiment distribution values. It is a list of *double* representing the number of positive, neutral, and negative reviews. **Note that**, these values will be used to provide the *Bar Values* in a bar chart. It is initialized with three zeros and will later be updated with the actual counts of positive, neutral, and negative reviews.
143+
![streaming-page-state.png](..%2Fimgs%2Fstreaming-page-state.png)
144+
145+
### 4. Trigger and extract data from API response
146+
147+
You can trigger the streaming API just like any other regular API. However, the method of extracting and parsing data differs from that of a standard API. Unlike non-streaming APIs, where you receive a response in an action output variable, the streaming API provides data through the following response actions:
148+
149+
* **onMessage:** This action is triggered every time a new piece of data is received from the streaming API. You can use this action to update your UI or perform any logic with the incoming data in real-time.
150+
* **onError:** This action is triggered when there is an error in the streaming connection. You can use this action to handle errors gracefully, such as displaying an error message to the user or attempting to reconnect.
151+
* **onClose:** This action is triggered when the streaming connection is closed. You can use this action to perform cleanup tasks or to notify the user that the stream has ended.
152+
153+
Whenever the data is received, you can access the response body via the **OnMessage > Set Variable menu > Action Parameters > OnMessageInput**. and then use the [**Response Stream Message Options**](/data-and-backend/api-calls/streaming-api-example-ai-review-summary#response-stream-message-options) to extract the data.
154+
155+
For this specific example, we use the *Server Sent Event Stream Data JSON* option and then use this JSON path `$['choices'][0]['delta']['content']` to retrieve the story data.
156+
157+
Here's how exactly you do it:
158+
159+
<div style={{
160+
position: 'relative',
161+
paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding
162+
height: 0,
163+
width: '100%'
164+
}}>
165+
<iframe
166+
src="https://demo.arcade.software/hWI8Kin5EcytoC3Pk4Vj?embed&show_copy_link=true"
167+
title=""
168+
style={{
169+
position: 'absolute',
170+
top: 0,
171+
left: 0,
172+
width: '100%',
173+
height: '100%',
174+
colorScheme: 'light'
175+
}}
176+
frameborder="0"
177+
loading="lazy"
178+
webkitAllowFullScreen
179+
mozAllowFullScreen
180+
allowFullScreen
181+
allow="clipboard-write">
182+
</iframe>
183+
</div>
184+
185+
### 5. Extract chart data
186+
187+
The API returns a detailed summary as text, but to display counts of positive, neutral, and negative reviews on chart, you need to extract these data from the text. To achieve this, you can write a simple [custom function](/customizing-your-app/custom-functions/custom-functions). Once the stream ends, pass the full text to the custom function to extract the relevant data and save the output in the `sentimentValues` page state variable we created earlier.
188+
189+
Here's how you do it:
190+
191+
<div style={{
192+
position: 'relative',
193+
paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding
194+
height: 0,
195+
width: '100%'
196+
}}>
197+
<iframe
198+
src="https://demo.arcade.software/U0TB9ENX5xSdfAVCB2BW?embed&show_copy_link=true"
199+
title=""
200+
style={{
201+
position: 'absolute',
202+
top: 0,
203+
left: 0,
204+
width: '100%',
205+
height: '100%',
206+
colorScheme: 'light'
207+
}}
208+
frameborder="0"
209+
loading="lazy"
210+
webkitAllowFullScreen
211+
mozAllowFullScreen
212+
allowFullScreen
213+
allow="clipboard-write">
214+
</iframe>
215+
</div>
216+
217+
<p></p>
218+
219+
:::tip
220+
* After saving the`sentimentValues`, it’s a good idea to remove the same data points from the generated review text to avoid redundancy.
221+
* Similarly, you can extract other data like 'pros' and 'cons' and display them the way you like.
222+
:::
223+
224+
## Response Stream Message Options
225+
226+
When working with Server Sent Events (SSE) in FlutterFlow, it's essential to understand how to process and handle the various components of the event messages. FlutterFlow provides several options that capture different parts of the SSE. Here are they:
227+
228+
### Server Sent Event Data JSON (Type: JSON)
229+
230+
This field captures the result of JSON parsing. For example:
231+
232+
```
233+
event: chat
234+
235+
data: {"response": "hello", "version": 7}
236+
237+
id: 2
238+
```
239+
The Server Sent Event Data JSON would be:
240+
241+
```
242+
{
243+
"response": "hello",
244+
"version": 7
245+
}
246+
```
247+
**Note that** If the data is not in JSON format, it will be null:
248+
249+
```
250+
event: ping
251+
252+
data: Server time is 2024-06-28T11:52:56+00:00
253+
254+
id: 2
255+
```
256+
The Server Sent Event Data JSON would be `null`.
257+
258+
### Server Sent Event Data Text (Type: String)
259+
260+
This field contains just the text of the "data" field from the SSE. If there are multiple "data" entries, they are concatenated with a new line. For example, from the event:
261+
262+
```
263+
event: ping
264+
265+
data: Server time is 2024-06-28T11:52:56+00:00
266+
267+
id: 2
268+
```
269+
The Server Sent Event Data Text would be: `Server time is 2024-06-28T11:52:56+00:00`
270+
271+
And from the event:
272+
273+
```
274+
event: journalEntry
275+
276+
data: Today I went to the park.
277+
278+
data: For Lunch I had a sandwich.
279+
280+
id: 3
281+
```
282+
The Server Sent Event Data Text would be:
283+
284+
```
285+
Today I went to the park.
286+
287+
For Lunch I had a sandwich.
288+
```
289+
### Server Sent Event Name (Type: String)
290+
291+
This field contains the text of the "event" field from the SSE. For example:
292+
293+
```
294+
event: ping
295+
296+
data: Server time is 2024-06-28T11:52:56+00:00
297+
298+
id: 2
299+
```
300+
The Server Sent Event Name would be `ping`.
301+
302+
### Server Sent Event ID (Type: Integer)
303+
304+
This field contains the text of the "id" field from the SSE, typically used to keep track of the last sent item from the server. For example:
305+
306+
```
307+
event: ping
308+
309+
data: Server time is 2024-06-28T11:52:56+00:00
310+
311+
id: 2
312+
```
313+
The Server Sent Event ID would be `2`.
314+
315+
### Server Sent Event Retry (Type: String?)
316+
317+
This field contains the "retry" field from the SSE, typically used to communicate to the client when to try reconnecting to the server.
318+
319+
### Message Text (Type: String)
320+
321+
This includes the entire Server Sent Event (SSE) message, including new lines and fields ('data', 'event', 'id', 'retry'). For example:
322+
323+
```
324+
event: ping
325+
326+
data: Server time is 2024-06-28T11:52:56+00:00
327+
328+
id: 2
329+
```
330+
## FAQs
331+
332+
<details>
333+
<summary>Why does it show 'null'?</summary>
334+
<p>
335+
336+
The "null" value appears in the Server Sent Event Data JSON field when the data is not in JSON format.
337+
338+
For instance, the following event data is not in JSON format:
339+
340+
341+
```
342+
event: ping
343+
data: Server time is 2024-06-28T11:52:56+00:00
344+
id: 2
345+
```
346+
The Server Sent Event Data JSON will be `null` because the data cannot be parsed as JSON.
347+
348+
You can fix this by using the following expression inside the [Code Expression](/advanced-functionality/code-expression) to handle the `null` case:
349+
350+
351+
```
352+
responseData ?? ''
353+
```
354+
This expression ensures that if `responseData` is `null`, it will return an empty string instead.
355+
</p>
356+
357+
</details>
358+
359+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"label": "Backend Query",
3+
"position": 2
4+
}

0 commit comments

Comments
 (0)