Skip to content

Commit 901b121

Browse files
committed
Sync open source content 🐝 (from ae9f562f1775b94bef5342dfe9b97ef4d9e569e7)
1 parent 9141ce8 commit 901b121

File tree

4 files changed

+304
-32
lines changed

4 files changed

+304
-32
lines changed

_meta.global.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,9 @@ const meta = {
397397
pagination: {
398398
title: "Enable Pagination",
399399
},
400+
polling: {
401+
title: "Enable Polling",
402+
},
400403
streaming: {
401404
title: "Enable Streaming",
402405
},
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
---
2+
description: "Learn how to simplify polling behaviors in Speakeasy-managed SDKs by creating SDKs with built-in polling methods."
3+
sidebar_label: "Add Polling"
4+
---
5+
6+
import { Callout } from "@/mdx/components";
7+
8+
# Adding polling to SDKs
9+
10+
Customize polling methods for each API operation using the `x-speakeasy-polling` extension.
11+
12+
Adding polling to an SDK enhances the developer experience by providing a consistent way to handle consuming code that waits for a particular API response change, which is common in API backends that perform asynchronous operations.
13+
14+
```go
15+
opts := []operations.Option{
16+
operations.WithPolling(client.PollingEndpointWaitForCompleted()),
17+
}
18+
response, err := client.PollingEndpoint(ctx, id, opts...)
19+
```
20+
21+
The polling methods, such as `PollingEndpointWaitForCompleted()` above, are generated from configuration within the API operation that declares one or more success criteria.
22+
23+
## Configuring polling
24+
25+
To configure polling, add the `x-speakeasy-polling` extension to the OpenAPI Specification document.
26+
27+
```yaml
28+
/example/{id}:
29+
get:
30+
parameters:
31+
- name: id
32+
in: path
33+
schema:
34+
type: string
35+
required: true
36+
responses:
37+
"200":
38+
description: OK
39+
content:
40+
application/json:
41+
schema:
42+
type: object
43+
properties:
44+
name:
45+
type: string
46+
status:
47+
type: string
48+
enum:
49+
- completed
50+
- errored
51+
- pending
52+
- running
53+
required:
54+
- name
55+
- status
56+
x-speakeasy-polling:
57+
- name: WaitForCompleted
58+
failureCriteria:
59+
- condition: $statusCode == 200
60+
- condition: $response.body#/status == "errored"
61+
successCriteria:
62+
- condition: $statusCode == 200
63+
- condition: $response.body#/status == "completed"
64+
```
65+
66+
The `x-speakeasy-polling` configuration supports multiple entries with unique names, which will generate unique polling methods with their required success criteria.
67+
68+
## Configuration options
69+
70+
### delaySeconds
71+
72+
Customize the delay before the API operation requests begin. By default, this is set to 1 second.
73+
74+
In this example:
75+
76+
```yaml
77+
x-speakeasy-polling:
78+
- name: WaitForCompleted
79+
delaySeconds: 5
80+
failureCriteria:
81+
- condition: $statusCode == 200
82+
- condition: $response.body#/status == "errored"
83+
successCriteria:
84+
- condition: $statusCode == 200
85+
- condition: $response.body#/status == "completed"
86+
```
87+
88+
The `WaitForCompleted` polling method makes the first API operation request after 5 seconds. Clients can override this value when using the SDK.
89+
90+
### failureCriteria
91+
92+
Customize the polling method to immediately return an error when defined conditions are met. This is useful when the API response contains any sort of "errored" or "failed" status value.
93+
94+
<Callout title="Note" type="info">
95+
It is not necessary to define failure criteria for API responses that are
96+
already considered errors, such as a 4XX or 5XX HTTP status code.
97+
</Callout>
98+
99+
In this example:
100+
101+
```yaml
102+
x-speakeasy-polling:
103+
- name: WaitForCompleted
104+
failureCriteria:
105+
- condition: $statusCode == 200
106+
- condition: $response.body#/status == "errored"
107+
successCriteria:
108+
- condition: $statusCode == 200
109+
- condition: $response.body#/status == "completed"
110+
```
111+
112+
The `WaitForCompleted` polling method will immediately return an error when the response body `status` property value is `errored`. Clients cannot override this behavior.
113+
114+
Refer to `successCriteria` for additional information about supported criteria as they share implementation details.
115+
116+
### intervalSeconds
117+
118+
Customize the interval between the API operation requests. By default, this is set to 1 second.
119+
120+
In this example:
121+
122+
```yaml
123+
x-speakeasy-polling:
124+
- name: WaitForCompleted
125+
failureCriteria:
126+
- condition: $statusCode == 200
127+
- condition: $response.body#/status == "errored"
128+
intervalSeconds: 5
129+
successCriteria:
130+
- condition: $statusCode == 200
131+
- condition: $response.body#/status == "completed"
132+
```
133+
134+
The `WaitForCompleted` polling method makes the next API operation request 5 seconds after the previous response. Clients can override this value when using the SDK.
135+
136+
### limitCount
137+
138+
Customize the total number of API operation requests before raising an error. By default, this is set to 60.
139+
140+
In this example:
141+
142+
```yaml
143+
x-speakeasy-polling:
144+
- name: WaitForCompleted
145+
failureCriteria:
146+
- condition: $statusCode == 200
147+
- condition: $response.body#/status == "errored"
148+
limitCount: 120
149+
successCriteria:
150+
- condition: $statusCode == 200
151+
- condition: $response.body#/status == "completed"
152+
```
153+
154+
The `WaitForCompleted` polling method makes at most 120 API operation requests. Clients can override this value when using the SDK.
155+
156+
### successCriteria
157+
158+
Configure the polling method success criteria. This configuration is required for all polling methods. The criteria themselves are a limited subset of [OpenAPI Arazzo criterion](https://spec.openapis.org/arazzo/latest.html#criterion-object). Each condition is a logical AND operation, evaluated in configuration order.
159+
160+
Supported conditions include:
161+
162+
- `$statusCode`: HTTP status code. Must be defined before response body conditions.
163+
- `$response.body`: HTTP response body data. A value within the data is defined with a JSONPath expression.
164+
165+
Supported operators include:
166+
167+
- `==`: Equals
168+
- `!=`: Not Equals
169+
170+
Certain language implementations, such as Go, also support using error status codes as success criteria. In these cases any SDK error that would have been returned to the SDK client are swallowed instead.
171+
172+
In this example:
173+
174+
```yaml
175+
x-speakeasy-polling:
176+
- name: WaitForNotFound
177+
successCriteria:
178+
- condition: $statusCode == 404
179+
```
180+
181+
The `WaitForNotFound` polling method immediately returns without error when the API operation returns a 404 Not Found HTTP status code.

docs/terraform/customize/entity-mapping.mdx

Lines changed: 97 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,9 @@ resource "yourprovider_order" "example" {
128128
```
129129

130130
<Callout title="Warning" type="warning">
131-
Properties above the `x-speakeasy-entity` annotation are flattened, which could cause conflicts. Apply the annotation carefully to align the structure of the Terraform provider with the API&apos;s intended interaction.
131+
Properties above the `x-speakeasy-entity` annotation are flattened, which
132+
could cause conflicts. Apply the annotation carefully to align the structure
133+
of the Terraform provider with the API&apos;s intended interaction.
132134
</Callout>
133135

134136
## Specify CRUD Operations for API Endpoints
@@ -163,23 +165,24 @@ paths:
163165
- pet
164166
summary: Info for a specific pet
165167
x-speakeasy-entity-operation: Pet#read
166-
update:
168+
put:
167169
tags:
168170
- pet
169171
summary: Update the pet
170172
x-speakeasy-entity-operation: Pet#update
171173
delete:
172174
tags:
173175
- pet
174-
summary: Delete the pet
176+
summary: Delete the pet
175177
x-speakeasy-entity-operation: Pet#delete
176178
```
177179
178180
<Callout title="Note" type="info">
179181
Terraform generation automatically handles pagination implementation details
180-
via the `x-speakeasy-pagination` [extension](/docs/customize/runtime/pagination).
181-
This includes paging through all responses and removing unnecessary pagination
182-
handling properties from the schema.
182+
via the `x-speakeasy-pagination`
183+
[extension](/docs/customize/runtime/pagination). This includes paging through
184+
all responses and removing unnecessary pagination handling properties from the
185+
schema.
183186
</Callout>
184187

185188
In this example, an automatically paginated Pets data resource is defined:
@@ -237,6 +240,83 @@ x-speakeasy-entity-operation:
237240

238241
One API operation for multiple resources can be combined with the entity operation ordering of [multiple API operations for one resource](#multiple-api-operations-for-one-resource) as necessary.
239242

243+
### API Operation Polling
244+
245+
Define automatic API operation polling logic for APIs with asynchronous behaviors via the `x-speakeasy-polling` and `x-speakeasy-entity-operation` extensions in the OpenAPI Specification document. Refer to the [SDK Polling documentation](/docs/customize/runtime/polling) for additional information about configuring `x-speakeasy-polling`.
246+
247+
In this example:
248+
249+
```yaml
250+
/task:
251+
post:
252+
x-speakeasy-entity-operation: Task#create#1
253+
/task/{id}:
254+
get:
255+
responses:
256+
"200":
257+
description: OK
258+
content:
259+
application/json:
260+
schema:
261+
type: object
262+
properties:
263+
name:
264+
type: string
265+
status:
266+
type: string
267+
enum:
268+
- completed
269+
- errored
270+
- pending
271+
- running
272+
required:
273+
- name
274+
- status
275+
x-speakeasy-polling:
276+
- name: WaitForCompleted
277+
failureCriteria:
278+
- condition: $statusCode == 200
279+
- condition: $response.body#/status == "errored"
280+
successCriteria:
281+
- condition: $statusCode == 200
282+
- condition: $response.body#/status == "completed"
283+
x-speakeasy-entity-operation:
284+
- Task#read
285+
- entityOperation: Task#create#2
286+
options:
287+
polling:
288+
name: WaitForCompleted
289+
```
290+
291+
The API operation is used for both the read operation and the second create operation, where the second create operation will use the `WaitForCompleted` polling method to ensure the success criteria is met before the resource logic (and therefore Terraform) continues.
292+
293+
There are `delaySeconds`, `intervalSeconds`, and `limitCount` configurations to override the `x-speakeasy-polling` configuration values for a specific entity operation.
294+
295+
In this example:
296+
297+
```yaml
298+
/task/{id}:
299+
get:
300+
x-speakeasy-polling:
301+
- name: WaitForCompleted
302+
failureCriteria:
303+
- condition: $statusCode == 200
304+
- condition: $response.body#/status == "errored"
305+
intervalSeconds: 5
306+
successCriteria:
307+
- condition: $statusCode == 200
308+
- condition: $response.body#/status == "completed"
309+
x-speakeasy-entity-operation:
310+
- Task#read
311+
- entityOperation: Task#create#2
312+
options:
313+
polling:
314+
name: WaitForCompleted
315+
intervalSeconds: 10
316+
```
317+
318+
The `WaitForCompleted` polling method for the API operation defaults to a 5 second interval, however the create entity operation overrides to a 10 second interval.
319+
240320
### Manual association between Operations and Resource / Data Sources
241321

242322
The default behavior within Speakeasy is to automatically infer a data source from all operations that have an `x-speakeasy-entity-operation: Entity#read` association defined.
@@ -282,12 +362,12 @@ paths:
282362
get:
283363
x-speakeasy-entity-operation: Example#read
284364
responses:
285-
'200':
365+
"200":
286366
description: OK
287367
content:
288368
application/json:
289369
schema:
290-
$ref: '#/components/schemas/ExampleResponse'
370+
$ref: "#/components/schemas/ExampleResponse"
291371
/example/{id}/subconfig:
292372
parameters:
293373
- name: id
@@ -298,13 +378,13 @@ paths:
298378
get:
299379
x-speakeasy-entity-operation: Example#read#2
300380
responses:
301-
'200':
381+
"200":
302382
description: OK
303383
content:
304384
application/json:
305385
schema:
306386
allOf:
307-
- $ref: '#/components/schemas/ExampleSubconfigResponse'
387+
- $ref: "#/components/schemas/ExampleSubconfigResponse"
308388
- x-speakeasy-wrapped-attribute: subconfig
309389
```
310390

@@ -320,7 +400,7 @@ paths:
320400
get:
321401
x-speakeasy-entity-operation: Things#read
322402
responses:
323-
'200':
403+
"200":
324404
description: OK
325405
content:
326406
application/json:
@@ -335,7 +415,7 @@ Since the response is `type: array`, Speakeasy wraps it in a `data` attribute fo
335415
Access in Terraform:
336416

337417
```hcl
338-
data.my_things_list.data[0].id
418+
data.example_things.data[0].id
339419
```
340420

341421
**Customize the wrapper name:**
@@ -346,7 +426,7 @@ paths:
346426
get:
347427
x-speakeasy-entity-operation: Things#read
348428
responses:
349-
'200':
429+
"200":
350430
description: OK
351431
content:
352432
application/json:
@@ -360,11 +440,13 @@ paths:
360440
Now the wrapping attribute is named `items` instead:
361441

362442
```hcl
363-
data.my_things_list.items[0].id
443+
data.example_things.items[0].id
364444
```
365445

366446
<Callout title="Note" type="info">
367-
The wrapping attribute name is a Terraform construct created by Speakeasy, completely separate from your API's response structure. Use `x-speakeasy-wrapped-attribute` to customize it.
447+
The wrapping attribute name is a Terraform construct created by Speakeasy,
448+
completely separate from your API's response structure. Use
449+
`x-speakeasy-wrapped-attribute` to customize it.
368450
</Callout>
369451

370452
### Resources with Soft Delete

0 commit comments

Comments
 (0)