Skip to content

Commit

Permalink
PDE-4295 Add support for throttle configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
kola-er committed Oct 3, 2023
1 parent 7908aba commit cfae948
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 2 deletions.
37 changes: 37 additions & 0 deletions packages/schema/docs/build/schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ This is automatically generated by the `npm run docs` command in `zapier-platfor
* [/SearchOrCreatesSchema](#searchorcreatesschema)
* [/SearchSchema](#searchschema)
* [/SearchesSchema](#searchesschema)
* [/ThrottleObjectSchema](#throttleobjectschema)
* [/TriggerSchema](#triggerschema)
* [/TriggersSchema](#triggersschema)
* [/VersionSchema](#versionschema)
Expand Down Expand Up @@ -126,6 +127,7 @@ Key | Required | Type | Description
`searchOrCreates` | no | [/SearchOrCreatesSchema](#searchorcreatesschema) | All the search-or-create combos for your app. You can create your own here, or Zapier will automatically register any from resources that define a search, a create, and a get (or define a searchOrCreate directly). Register non-resource search-or-creates here as well.
`searchAndCreates` | no | [/SearchAndCreatesSchema](#searchandcreatesschema) | An alias for "searchOrCreates".
`flags` | no | [/AppFlagsSchema](#appflagsschema) | Top-level app options
`throttle` | no | [/ThrottleObjectSchema](#throttleobjectschema) | Zapier uses this configuration to throttle actions' perform method, individually, when their number of invocations exceeds the limit within a specific window. When set here, it is the default throttle configuration used on all the actions of an integration. And it can be overwritten on each action in the action's operation object.



Expand Down Expand Up @@ -390,6 +392,7 @@ Key | Required | Type | Description
`outputFields` | no | [/DynamicFieldsSchema](#dynamicfieldsschema) | What fields of data will this return? Will use resource outputFields if missing, will also use sample if available.
`sample` | **yes** (with exceptions, see description) | `object` | What does a sample of data look like? Will use resource sample if missing. Requirement waived if `display.hidden` is true or if this belongs to a resource that has a top-level sample
`lock` | no | [/LockObjectSchema](#lockobjectschema) | **INTERNAL USE ONLY**. Zapier uses this configuration for internal operation locking.
`throttle` | no | [/ThrottleObjectSchema](#throttleobjectschema) | Zapier uses this configuration to throttle an action's perform method when its number of invocations exceeds the limit within a specific window.

#### Examples

Expand Down Expand Up @@ -422,6 +425,7 @@ Key | Required | Type | Description
`outputFields` | no | [/DynamicFieldsSchema](#dynamicfieldsschema) | What fields of data will this return? Will use resource outputFields if missing, will also use sample if available.
`sample` | **yes** (with exceptions, see description) | `object` | What does a sample of data look like? Will use resource sample if missing. Requirement waived if `display.hidden` is true or if this belongs to a resource that has a top-level sample
`lock` | no | [/LockObjectSchema](#lockobjectschema) | **INTERNAL USE ONLY**. Zapier uses this configuration for internal operation locking.
`throttle` | no | [/ThrottleObjectSchema](#throttleobjectschema) | Zapier uses this configuration to throttle an action's perform method when its number of invocations exceeds the limit within a specific window.
`shouldLock` | no | `boolean` | Should this action be performed one at a time (avoid concurrency)?

#### Examples
Expand Down Expand Up @@ -543,6 +547,7 @@ Key | Required | Type | Description
`outputFields` | no | [/DynamicFieldsSchema](#dynamicfieldsschema) | What fields of data will this return? Will use resource outputFields if missing, will also use sample if available.
`sample` | **yes** (with exceptions, see description) | `object` | What does a sample of data look like? Will use resource sample if missing. Requirement waived if `display.hidden` is true or if this belongs to a resource that has a top-level sample
`lock` | no | [/LockObjectSchema](#lockobjectschema) | **INTERNAL USE ONLY**. Zapier uses this configuration for internal operation locking.
`throttle` | no | [/ThrottleObjectSchema](#throttleobjectschema) | Zapier uses this configuration to throttle an action's perform method when its number of invocations exceeds the limit within a specific window.

#### Examples

Expand Down Expand Up @@ -2056,6 +2061,38 @@ Key | Required | Type | Description

-----

## /ThrottleObjectSchema

Zapier uses this configuration to throttle an action's perform method when its number of invocations exceeds the limit within a specific window.

#### Details

* **Type** - `object`
* [**Source Code**](https://github.com/zapier/zapier-platform/blob/[email protected]/packages/schema/lib/schemas/ThrottleObjectSchema.js)

#### Properties

Key | Required | Type | Description
--- | -------- | ---- | -----------
`window` | **yes** | `integer` | The timeframe in seconds to track the number of invocations to an action's perform method before resetting, to start all over again.
`limit` | **yes** | `integer` | The maximum number of invocations to an action's perform method, allowed within the timeframe window.
`scope` | no | `array`[`string` in (`'user'`, `'auth'`, `'account'`)] | The requester's attribute with which the invocations would be throttled by. You can set the scope to one or more of the following: 'user' - Throttles based on user ids. 'auth' - Throttles based on auth ids. 'account' - Throttles based on account ids for all users under a single account. By default, throttling is scoped to the account.

#### Examples

* `{ window: 60, limit: 100 }`
* `{ window: 600, limit: 100, scope: [ 'account', 'user' ] }`
* `{ window: 3600, limit: 10, scope: [ 'auth' ] }`

#### Anti-Examples

* `{ window: 60, limit: 100, scope: [ 'zap' ] }` - _Invalid scope provided: `zap`._
* `{ limit: 10 }` - _Missing required key: `window`._
* `{ window: 600 }` - _Missing required key: `limit`._
* `{}` - _Missing required keys: `window` and `limit`._

-----

## /TriggerSchema

How will Zapier get notified of new objects?
Expand Down
41 changes: 41 additions & 0 deletions packages/schema/exported-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@
"description": "Top-level app options",
"$ref": "/AppFlagsSchema"
},
"throttle": {
"description": "Zapier uses this configuration to throttle actions' perform method, individually, when their number of invocations exceeds the limit within a specific window. When set here, it is the default throttle configuration used on all the actions of an integration. And it can be overwritten on each action in the action's operation object.",
"$ref": "/ThrottleObjectSchema"
},
"legacy": {
"description": "**INTERNAL USE ONLY**. Zapier uses this to hold properties from a legacy Web Builder app.",
"type": "object",
Expand Down Expand Up @@ -652,6 +656,31 @@
"minProperties": 1
}
},
"ThrottleObjectSchema": {
"id": "/ThrottleObjectSchema",
"description": "Zapier uses this configuration to throttle an action's perform method when its number of invocations exceeds the limit within a specific window.",
"type": "object",
"required": ["window", "limit"],
"properties": {
"window": {
"description": "The timeframe in seconds to track the number of invocations to an action's perform method before resetting, to start all over again.",
"type": "integer"
},
"limit": {
"description": "The maximum number of invocations to an action's perform method, allowed within the timeframe window.",
"type": "integer"
},
"scope": {
"description": "The requester's attribute with which the invocations would be throttled by. You can set the scope to one or more of the following: 'user' - Throttles based on user ids. 'auth' - Throttles based on auth ids. 'account' - Throttles based on account ids for all users under a single account. By default, throttling is scoped to the account.",
"type": "array",
"items": {
"enum": ["user", "auth", "account"],
"type": "string"
}
}
},
"additionalProperties": false
},
"BasicDisplaySchema": {
"id": "/BasicDisplaySchema",
"description": "Represents user information for a trigger, search, or create.",
Expand Down Expand Up @@ -737,6 +766,10 @@
"lock": {
"description": "**INTERNAL USE ONLY**. Zapier uses this configuration for internal operation locking.",
"$ref": "/LockObjectSchema"
},
"throttle": {
"description": "Zapier uses this configuration to throttle an action's perform method when its number of invocations exceeds the limit within a specific window.",
"$ref": "/ThrottleObjectSchema"
}
},
"additionalProperties": false
Expand Down Expand Up @@ -954,6 +987,10 @@
"lock": {
"description": "**INTERNAL USE ONLY**. Zapier uses this configuration for internal operation locking.",
"$ref": "/LockObjectSchema"
},
"throttle": {
"description": "Zapier uses this configuration to throttle an action's perform method when its number of invocations exceeds the limit within a specific window.",
"$ref": "/ThrottleObjectSchema"
}
},
"additionalProperties": false
Expand Down Expand Up @@ -1318,6 +1355,10 @@
"description": "**INTERNAL USE ONLY**. Zapier uses this configuration for internal operation locking.",
"$ref": "/LockObjectSchema"
},
"throttle": {
"description": "Zapier uses this configuration to throttle an action's perform method when its number of invocations exceeds the limit within a specific window.",
"$ref": "/ThrottleObjectSchema"
},
"shouldLock": {
"description": "Should this action be performed one at a time (avoid concurrency)?",
"type": "boolean"
Expand Down
7 changes: 7 additions & 0 deletions packages/schema/lib/schemas/AppSchema.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const VersionSchema = require('./VersionSchema');
const MiddlewaresSchema = require('./MiddlewaresSchema');
const HydratorsSchema = require('./HydratorsSchema');
const AppFlagsSchema = require('./AppFlagsSchema');
const ThrottleObjectSchema = require('./ThrottleObjectSchema');

module.exports = makeSchema(
{
Expand Down Expand Up @@ -105,6 +106,11 @@ module.exports = makeSchema(
description: 'Top-level app options',
$ref: AppFlagsSchema.id,
},
throttle: {
description:
'Zapier uses this configuration to throttle actions\' perform method, individually, when their number of invocations exceeds the limit within a specific window. When set here, it is the default throttle configuration used on all the actions of an integration. And it can be overwritten on each action in the action\'s operation object.',
$ref: ThrottleObjectSchema.id,
},
legacy: {
description:
'**INTERNAL USE ONLY**. Zapier uses this to hold properties from a legacy Web Builder app.',
Expand Down Expand Up @@ -150,5 +156,6 @@ module.exports = makeSchema(
MiddlewaresSchema,
HydratorsSchema,
AppFlagsSchema,
ThrottleObjectSchema,
]
);
1 change: 1 addition & 0 deletions packages/schema/lib/schemas/BasicActionOperationSchema.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ BasicActionOperationSchema.properties = {
outputFields: BasicActionOperationSchema.properties.outputFields,
sample: BasicActionOperationSchema.properties.sample,
lock: BasicActionOperationSchema.properties.lock,
throttle: BasicActionOperationSchema.properties.throttle,
};

BasicActionOperationSchema.examples = [
Expand Down
8 changes: 7 additions & 1 deletion packages/schema/lib/schemas/BasicOperationSchema.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const RequestSchema = require('./RequestSchema');
const ResultsSchema = require('./ResultsSchema');
const KeySchema = require('./KeySchema');
const LockObjectSchema = require('./LockObjectSchema');
const ThrottleObjectSchema = require('./ThrottleObjectSchema');

module.exports = makeSchema(
{
Expand Down Expand Up @@ -56,6 +57,11 @@ module.exports = makeSchema(
'**INTERNAL USE ONLY**. Zapier uses this configuration for internal operation locking.',
$ref: LockObjectSchema.id,
},
throttle: {
description:
'Zapier uses this configuration to throttle an action\'s perform method when its number of invocations exceeds the limit within a specific window.',
$ref: ThrottleObjectSchema.id,
},
},
examples: [
{
Expand All @@ -75,5 +81,5 @@ module.exports = makeSchema(
],
additionalProperties: false,
},
[DynamicFieldsSchema, FunctionSchema, KeySchema, LockObjectSchema, RequestSchema, ResultsSchema]
[DynamicFieldsSchema, FunctionSchema, KeySchema, LockObjectSchema, RequestSchema, ResultsSchema, ThrottleObjectSchema]
);
70 changes: 70 additions & 0 deletions packages/schema/lib/schemas/ThrottleObjectSchema.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
'use strict';

const makeSchema = require('../utils/makeSchema');

module.exports = makeSchema({
id: '/ThrottleObjectSchema',
description:
'Zapier uses this configuration to throttle an action\'s perform method when its number of invocations exceeds the limit within a specific window.',
type: 'object',
required: ['window', 'limit'],
properties: {
window: {
description:
'The timeframe in seconds to track the number of invocations to an action\'s perform method before resetting, to start all over again.',
type: 'integer',
},
limit: {
description:
'The maximum number of invocations to an action\'s perform method, allowed within the timeframe window.',
type: 'integer',
},
scope: {
description: `The requester's attribute with which the invocations would be throttled by. You can set the scope to one or more of the following: 'user' - Throttles based on user ids. 'auth' - Throttles based on auth ids. 'account' - Throttles based on account ids for all users under a single account. By default, throttling is scoped to the account.`,
type: 'array',
items: {
enum: ['user', 'auth', 'account'],
type: 'string',
},
},
},
examples: [
{
window: 60,
limit: 100,
},
{
window: 600,
limit: 100,
scope: ['account', 'user'],
},
{
window: 3600,
limit: 10,
scope: ['auth'],
},
],
antiExamples: [
{
example: {
window: 60,
limit: 100,
scope: ['zap'],
},
reason: 'Invalid scope provided: `zap`.',
},
{
example: {limit: 10},
reason: 'Missing required key: `window`.',
},
{
example: {window: 600},
reason: 'Missing required key: `limit`.',
},
{
example: {},
reason: 'Missing required keys: `window` and `limit`.',
},
],
additionalProperties: false,
});
2 changes: 1 addition & 1 deletion packages/schema/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const appDefinition = require('../examples/definition.json');

const copy = (o) => JSON.parse(JSON.stringify(o));

const NUM_SCHEMAS = 53; // changes regularly as we expand
const NUM_SCHEMAS = 54; // changes regularly as we expand

describe('app', () => {
describe('validation', () => {
Expand Down

0 comments on commit cfae948

Please sign in to comment.