vybekiit 0.7.0 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +1697 -562
- package/dist/global-skills/add-ai/SKILL.md +1 -1
- package/dist/global-skills/add-analytics/SKILL.md +1 -1
- package/dist/global-skills/add-blog/SKILL.md +1 -1
- package/dist/global-skills/add-crud/SKILL.md +1 -1
- package/dist/global-skills/add-files/SKILL.md +1 -1
- package/dist/global-skills/add-images/SKILL.md +1 -1
- package/dist/global-skills/add-language/SKILL.md +1 -1
- package/dist/global-skills/add-notifications/SKILL.md +1 -1
- package/dist/global-skills/add-realtime/SKILL.md +1 -1
- package/dist/global-skills/add-route/SKILL.md +1 -1
- package/dist/global-skills/add-search/SKILL.md +1 -1
- package/dist/global-skills/add-signin/SKILL.md +1 -1
- package/dist/global-skills/add-teams/SKILL.md +1 -1
- package/dist/global-skills/add-upload/SKILL.md +1 -1
- package/dist/global-skills/aws-serverless/SKILL.md +44 -44
- package/dist/global-skills/aws-serverless/assets/powertools-handler.py +1 -2
- package/dist/global-skills/aws-serverless/references/api-gateway.md +470 -50
- package/dist/global-skills/aws-serverless/references/architecture.md +186 -47
- package/dist/global-skills/aws-serverless/references/concurrency.md +158 -44
- package/dist/global-skills/aws-serverless/references/deployment.md +1 -1
- package/dist/global-skills/aws-serverless/references/event-sources.md +391 -72
- package/dist/global-skills/aws-serverless/references/lambda.md +428 -69
- package/dist/global-skills/aws-serverless/references/orchestration.md +384 -65
- package/dist/global-skills/aws-serverless/references/production.md +415 -78
- package/dist/global-skills/aws-serverless/references/troubleshooting.md +626 -79
- package/dist/global-skills/back-up-my-code/SKILL.md +1 -1
- package/dist/global-skills/buy-domain/SKILL.md +1 -1
- package/dist/global-skills/check-safety/SKILL.md +1 -1
- package/dist/global-skills/configure-capabilities/SKILL.md +1 -1
- package/dist/global-skills/connect-account/SKILL.md +1 -1
- package/dist/global-skills/connect-account-backend/SKILL.md +1 -1
- package/dist/global-skills/design-my-data/SKILL.md +1 -1
- package/dist/global-skills/doctor/SKILL.md +1 -1
- package/dist/global-skills/feedback/SKILL.md +63 -0
- package/dist/global-skills/go-live/SKILL.md +1 -1
- package/dist/global-skills/harden/SKILL.md +1 -1
- package/dist/global-skills/instrument-feature-flags/references/usage.md +0 -35
- package/dist/global-skills/instrument-product-analytics/SKILL.md +1 -1
- package/dist/global-skills/instrument-product-analytics/references/android.md +0 -36
- package/dist/global-skills/instrument-product-analytics/references/configuration.md +0 -1
- package/dist/global-skills/instrument-product-analytics/references/flutter.md +0 -37
- package/dist/global-skills/instrument-product-analytics/references/posthog-python.md +2 -3
- package/dist/global-skills/instrument-product-analytics/references/usage.md +0 -35
- package/dist/global-skills/manifest.json +2 -1
- package/dist/global-skills/neon/SKILL.md +20 -27
- package/dist/global-skills/neon-ai-gateway/SKILL.md +2 -68
- package/dist/global-skills/neon-functions/SKILL.md +7 -7
- package/dist/global-skills/neon-object-storage/SKILL.md +2 -2
- package/dist/global-skills/neon-postgres/SKILL.md +5 -5
- package/dist/global-skills/neon-postgres-branches/SKILL.md +1 -1
- package/dist/global-skills/onboarding/SKILL.md +1 -1
- package/dist/global-skills/plan-my-idea/SKILL.md +1 -1
- package/dist/global-skills/publish-app/SKILL.md +1 -1
- package/dist/global-skills/publish-extension/SKILL.md +1 -1
- package/dist/global-skills/reset-password/SKILL.md +1 -1
- package/dist/global-skills/save-data/SKILL.md +1 -1
- package/dist/global-skills/setup-email/SKILL.md +1 -1
- package/dist/global-skills/setup-payments/SKILL.md +1 -1
- package/dist/global-skills/setup-sms/SKILL.md +1 -1
- package/dist/global-skills/sign-in-with-email-link/SKILL.md +1 -1
- package/dist/global-skills/sign-in-with-google/SKILL.md +1 -1
- package/dist/global-skills/sign-in-with-phone/SKILL.md +1 -1
- package/dist/global-skills/stripe-best-practices/SKILL.md +6 -11
- package/dist/global-skills/stripe-best-practices/references/billing.md +0 -5
- package/dist/global-skills/stripe-best-practices/references/payments.md +2 -4
- package/dist/global-skills/stripe-best-practices/references/tax.md +8 -78
- package/dist/global-skills/track-errors/SKILL.md +1 -1
- package/dist/global-skills/update-kit/SKILL.md +1 -1
- package/dist/global-skills/wire-auth/SKILL.md +1 -1
- package/dist/global-skills/wire-database/SKILL.md +1 -1
- package/dist/global-skills/wire-email/SKILL.md +1 -1
- package/dist/global-skills/wire-payments/SKILL.md +1 -1
- package/package.json +8 -8
- package/dist/global-skills/email-best-practices/.github/workflows/sync-skills.yml +0 -30
- package/dist/global-skills/email-best-practices/README.md +0 -63
- package/dist/global-skills/email-best-practices/references/accessibility.md +0 -189
- package/dist/global-skills/email-best-practices/references/compliance.md +0 -125
- package/dist/global-skills/email-best-practices/references/deliverability.md +0 -121
- package/dist/global-skills/email-best-practices/references/email-capture.md +0 -129
- package/dist/global-skills/email-best-practices/references/email-types.md +0 -173
- package/dist/global-skills/email-best-practices/references/list-management.md +0 -157
- package/dist/global-skills/email-best-practices/references/marketing-emails.md +0 -115
- package/dist/global-skills/email-best-practices/references/sending-reliability.md +0 -155
- package/dist/global-skills/email-best-practices/references/transactional-email-catalog.md +0 -418
- package/dist/global-skills/email-best-practices/references/transactional-emails.md +0 -92
- package/dist/global-skills/email-best-practices/references/webhooks-events.md +0 -167
- package/dist/global-skills/email-best-practices/tests/README.md +0 -35
- package/dist/global-skills/email-best-practices/tests/scenarios/01-spam-deliverability.md +0 -46
- package/dist/global-skills/email-best-practices/tests/scenarios/02-multi-region-compliance.md +0 -48
- package/dist/global-skills/email-best-practices/tests/scenarios/03-retry-idempotency.md +0 -36
- package/dist/global-skills/email-best-practices/tests/scenarios/04-webhook-bounce-handling.md +0 -52
- package/dist/global-skills/email-best-practices/tests/scenarios/05-new-saas-email-plan.md +0 -51
- package/dist/global-skills/neon-postgres/references/neon-sdk.md +0 -262
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
# API Gateway Reference
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Quick-reference for REST API, HTTP API, WebSocket API — debugging, configuration, and quotas.
|
|
4
4
|
|
|
5
5
|
## Contents
|
|
6
6
|
|
|
7
|
-
- [REST vs HTTP API
|
|
8
|
-
- [
|
|
9
|
-
- [
|
|
10
|
-
- [
|
|
7
|
+
- [REST vs HTTP API Comparison](#rest-vs-http-api-comparison)
|
|
8
|
+
- [CORS Debugging](#cors-debugging)
|
|
9
|
+
- [Lambda Authorizers](#lambda-authorizers)
|
|
10
|
+
- [Throttling and Quotas](#throttling-and-quotas)
|
|
11
11
|
- [WebSocket APIs](#websocket-apis)
|
|
12
|
-
- [
|
|
12
|
+
- [502/504 Debugging](#502504-debugging)
|
|
13
13
|
|
|
14
14
|
---
|
|
15
15
|
|
|
16
|
-
## REST vs HTTP API
|
|
16
|
+
## REST vs HTTP API Comparison
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
### Decision Tree
|
|
19
19
|
|
|
20
20
|
```
|
|
21
21
|
Need any of these? → REST API
|
|
@@ -34,100 +34,520 @@ Need any of these? → REST API
|
|
|
34
34
|
None of the above? → HTTP API (lower latency, simpler)
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
+
### Feature Comparison
|
|
38
|
+
|
|
39
|
+
| Feature | REST API | HTTP API |
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| **Latency** | Higher | Lower |
|
|
42
|
+
| **Endpoint types** | Edge, Regional, Private | Regional only |
|
|
43
|
+
| **AWS WAF** | Yes | No |
|
|
44
|
+
| **API keys / usage plans** | Yes | No |
|
|
45
|
+
| **Per-client throttling** | Yes | No |
|
|
46
|
+
| **Request validation** | Yes | No |
|
|
47
|
+
| **Body transformation (VTL)** | Yes | No |
|
|
48
|
+
| **Parameter mapping** | Yes | Yes |
|
|
49
|
+
| **Caching (built-in)** | Yes | No |
|
|
50
|
+
| **Custom domains** | Yes | Yes |
|
|
51
|
+
| **Lambda authorizers** | Yes (TOKEN + REQUEST) | Yes (REQUEST only) |
|
|
52
|
+
| **JWT authorizers (native)** | No | Yes |
|
|
53
|
+
| **IAM auth** | Yes | Yes |
|
|
54
|
+
| **Cognito (native)** | Yes | Yes (via JWT) |
|
|
55
|
+
| **Resource policies** | Yes | No |
|
|
56
|
+
| **Mutual TLS** | Yes | Yes |
|
|
57
|
+
| **CORS setup** | Manual OPTIONS method | Built-in config |
|
|
58
|
+
| **Automatic deployments** | No | Yes |
|
|
59
|
+
| **Canary deployments** | Yes | No |
|
|
60
|
+
| **Custom gateway responses** | Yes | No |
|
|
61
|
+
| **Execution logs** | Yes | No |
|
|
62
|
+
| **Access logs (CloudWatch)** | Yes | Yes |
|
|
63
|
+
| **Access logs (Firehose)** | Yes | No |
|
|
64
|
+
| **X-Ray tracing** | Yes | No |
|
|
65
|
+
| **Mock integrations** | Yes | No |
|
|
66
|
+
| **Private integrations (NLB)** | Yes | Yes |
|
|
67
|
+
| **Private integrations (ALB)** | Yes | Yes |
|
|
68
|
+
| **Private integrations (Cloud Map)** | No | Yes |
|
|
69
|
+
| **Response streaming** | Yes | No |
|
|
70
|
+
| **Console test invocations** | Yes | No |
|
|
71
|
+
| **Integration timeout** | 50ms–29s (configurable) | 30s hard max |
|
|
72
|
+
| **Payload size** | 10 MB | 10 MB |
|
|
73
|
+
|
|
74
|
+
> **REST API streaming caveats:** Response streaming via REST API proxy integration does not support built-in caching, response transforms (VTL), or WAF inspection of streamed content. Idle timeouts apply, and a 2 MBps bandwidth cap applies after the first 10 MB (Function URLs apply the cap after 6 MB).
|
|
75
|
+
|
|
37
76
|
---
|
|
38
77
|
|
|
39
|
-
##
|
|
78
|
+
## CORS Debugging
|
|
79
|
+
|
|
80
|
+
### Proxy vs Non-Proxy
|
|
40
81
|
|
|
41
|
-
| |
|
|
82
|
+
| Aspect | Proxy integration | Non-proxy integration |
|
|
42
83
|
|---|---|---|
|
|
43
|
-
|
|
|
44
|
-
|
|
|
45
|
-
|
|
|
46
|
-
| Response streaming | Yes (proxy, STREAM mode) | No |
|
|
84
|
+
| Who returns CORS headers? | **Your Lambda function** | **API Gateway** (method response) |
|
|
85
|
+
| OPTIONS method needed? | Yes (or use mock) | Yes (mock integration) |
|
|
86
|
+
| Where to configure? | In your code | In API Gateway console/IaC |
|
|
47
87
|
|
|
48
|
-
|
|
88
|
+
### Debugging Flowchart
|
|
49
89
|
|
|
50
|
-
|
|
90
|
+
```
|
|
91
|
+
"Cross-Origin Request Blocked"?
|
|
92
|
+
│
|
|
93
|
+
├─ YES → Which integration type?
|
|
94
|
+
│ │
|
|
95
|
+
│ ├─ PROXY → Lambda MUST return CORS headers
|
|
96
|
+
│ │ ├─ Access-Control-Allow-Origin
|
|
97
|
+
│ │ ├─ Access-Control-Allow-Methods
|
|
98
|
+
│ │ └─ Access-Control-Allow-Headers
|
|
99
|
+
│ │
|
|
100
|
+
│ └─ NON-PROXY → Configure in API Gateway:
|
|
101
|
+
│ ├─ Create OPTIONS method (mock integration)
|
|
102
|
+
│ ├─ Add 200 response with CORS headers
|
|
103
|
+
│ └─ Add CORS headers to actual method responses
|
|
104
|
+
│
|
|
105
|
+
├─ OPTIONS returning 200?
|
|
106
|
+
│ ├─ NO → OPTIONS method missing or misconfigured
|
|
107
|
+
│ └─ YES → Check actual method response headers
|
|
108
|
+
│
|
|
109
|
+
└─ 502 on OPTIONS?
|
|
110
|
+
└─ Binary media types set to */* → fix below
|
|
111
|
+
```
|
|
51
112
|
|
|
52
|
-
|
|
113
|
+
### Common CORS Mistakes
|
|
53
114
|
|
|
54
|
-
|
|
115
|
+
| # | Mistake | Fix |
|
|
116
|
+
|---|---|---|
|
|
117
|
+
| 1 | No CORS headers in Lambda (proxy integration) | Add headers to every Lambda response |
|
|
118
|
+
| 2 | Missing OPTIONS method (REST API, non-proxy) | Create OPTIONS with mock integration |
|
|
119
|
+
| 3 | Binary media types `*/*` breaks OPTIONS | Set `contentHandling: CONVERT_TO_TEXT` on OPTIONS |
|
|
120
|
+
| 4 | `Allow-Origin: *` with `credentials: include` | Specify exact origin, not wildcard |
|
|
121
|
+
| 5 | Not redeploying API after CORS changes | Redeploy the stage |
|
|
122
|
+
| 6 | Missing `Allow-Headers` for custom headers | List all headers the client sends |
|
|
123
|
+
| 7 | Gateway 4XX/5XX responses lack CORS headers | Add CORS headers to gateway responses |
|
|
124
|
+
|
|
125
|
+
### Lambda CORS Headers — Python
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
def handler(event, context):
|
|
129
|
+
return {
|
|
130
|
+
"statusCode": 200,
|
|
131
|
+
"headers": {
|
|
132
|
+
"Access-Control-Allow-Origin": "https://example.com",
|
|
133
|
+
"Access-Control-Allow-Methods": "OPTIONS,POST,GET,PUT,DELETE",
|
|
134
|
+
"Access-Control-Allow-Headers": "Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token",
|
|
135
|
+
},
|
|
136
|
+
"body": json.dumps({"message": "success"}),
|
|
137
|
+
}
|
|
138
|
+
```
|
|
55
139
|
|
|
56
|
-
###
|
|
140
|
+
### Lambda CORS Headers — TypeScript
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
export const handler = async (event: any) => ({
|
|
144
|
+
statusCode: 200,
|
|
145
|
+
headers: {
|
|
146
|
+
"Access-Control-Allow-Origin": "https://example.com",
|
|
147
|
+
"Access-Control-Allow-Methods": "OPTIONS,POST,GET,PUT,DELETE",
|
|
148
|
+
"Access-Control-Allow-Headers": "Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token",
|
|
149
|
+
},
|
|
150
|
+
body: JSON.stringify({ message: "success" }),
|
|
151
|
+
});
|
|
152
|
+
```
|
|
57
153
|
|
|
58
|
-
|
|
154
|
+
### Binary Media Types `*/*` Fix
|
|
59
155
|
|
|
60
156
|
```bash
|
|
61
|
-
|
|
157
|
+
# Fix OPTIONS integration request
|
|
158
|
+
aws apigateway update-integration \
|
|
159
|
+
--rest-api-id API_ID --resource-id RES_ID \
|
|
160
|
+
--http-method OPTIONS \
|
|
161
|
+
--patch-operations op='replace',path='/contentHandling',value='CONVERT_TO_TEXT'
|
|
162
|
+
|
|
163
|
+
# Fix OPTIONS integration response
|
|
164
|
+
aws apigateway update-integration-response \
|
|
165
|
+
--rest-api-id API_ID --resource-id RES_ID \
|
|
166
|
+
--http-method OPTIONS --status-code 200 \
|
|
167
|
+
--patch-operations op='replace',path='/contentHandling',value='CONVERT_TO_TEXT'
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Lambda Authorizers
|
|
173
|
+
|
|
174
|
+
### TOKEN vs REQUEST Authorizer
|
|
175
|
+
|
|
176
|
+
| Feature | TOKEN | REQUEST |
|
|
177
|
+
|---|---|---|
|
|
178
|
+
| Identity source | Single header (bearer token) | Headers, query strings, stage vars, `$context` |
|
|
179
|
+
| Cache key | Token header value | All specified identity sources |
|
|
180
|
+
| Token validation regex | Yes | No |
|
|
181
|
+
| Fine-grained policies | Limited | Yes (multiple sources) |
|
|
182
|
+
| Available on | REST API only | REST API + HTTP API |
|
|
183
|
+
| **Recommendation** | Legacy | **Preferred** |
|
|
184
|
+
|
|
185
|
+
> **Use REQUEST authorizers for new APIs.** TOKEN is legacy.
|
|
186
|
+
|
|
187
|
+
### Caching Behavior
|
|
188
|
+
|
|
189
|
+
| Setting | Detail |
|
|
190
|
+
|---|---|
|
|
191
|
+
| Default TTL | 300 seconds |
|
|
192
|
+
| Range | 0 (disabled) – 3600 seconds |
|
|
193
|
+
| Cache key (TOKEN) | Header value from token source |
|
|
194
|
+
| Cache key (REQUEST) | All specified identity sources combined |
|
|
195
|
+
| **Critical** | Cached policy applies to **ALL methods/resources** |
|
|
196
|
+
|
|
197
|
+
If any specified identity source is missing/null/empty → 401 returned **without** invoking Lambda.
|
|
198
|
+
|
|
199
|
+
### REQUEST Authorizer — Python
|
|
200
|
+
|
|
201
|
+
```python
|
|
202
|
+
def lambda_handler(event, context):
|
|
203
|
+
token = event["headers"].get("Authorization", "")
|
|
204
|
+
is_authorized = verify_token(token) # Your auth logic
|
|
205
|
+
|
|
206
|
+
return {
|
|
207
|
+
"principalId": "user",
|
|
208
|
+
"policyDocument": {
|
|
209
|
+
"Version": "2012-10-17",
|
|
210
|
+
"Statement": [{
|
|
211
|
+
"Action": "execute-api:Invoke",
|
|
212
|
+
"Effect": "Allow" if is_authorized else "Deny",
|
|
213
|
+
"Resource": event["methodArn"],
|
|
214
|
+
}],
|
|
215
|
+
},
|
|
216
|
+
"context": {"userId": "user", "scope": "read:items"},
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### REQUEST Authorizer — TypeScript
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
import { APIGatewayAuthorizerResult, APIGatewayRequestAuthorizerEvent } from "aws-lambda";
|
|
224
|
+
|
|
225
|
+
export const handler = async (
|
|
226
|
+
event: APIGatewayRequestAuthorizerEvent
|
|
227
|
+
): Promise<APIGatewayAuthorizerResult> => {
|
|
228
|
+
const token = event.headers?.Authorization ?? "";
|
|
229
|
+
const isAuthorized = verifyToken(token); // Your auth logic
|
|
230
|
+
|
|
231
|
+
return {
|
|
232
|
+
principalId: "user",
|
|
233
|
+
policyDocument: {
|
|
234
|
+
Version: "2012-10-17",
|
|
235
|
+
Statement: [{
|
|
236
|
+
Action: "execute-api:Invoke",
|
|
237
|
+
Effect: isAuthorized ? "Allow" : "Deny",
|
|
238
|
+
Resource: event.methodArn,
|
|
239
|
+
}],
|
|
240
|
+
},
|
|
241
|
+
context: { userId: "user", scope: "read:items" },
|
|
242
|
+
};
|
|
243
|
+
};
|
|
62
244
|
```
|
|
63
245
|
|
|
64
|
-
###
|
|
246
|
+
### HTTP API JWT Authorizer (Native — No Lambda)
|
|
247
|
+
|
|
248
|
+
No Lambda function needed. Configure directly on the API:
|
|
249
|
+
|
|
250
|
+
```yaml
|
|
251
|
+
# SAM / CloudFormation
|
|
252
|
+
MyHttpApi:
|
|
253
|
+
Type: AWS::Serverless::HttpApi
|
|
254
|
+
Properties:
|
|
255
|
+
Auth:
|
|
256
|
+
DefaultAuthorizer: MyJwtAuth
|
|
257
|
+
Authorizers:
|
|
258
|
+
MyJwtAuth:
|
|
259
|
+
AuthorizationScopes:
|
|
260
|
+
- read:items
|
|
261
|
+
IdentitySource: $request.header.Authorization
|
|
262
|
+
JwtConfiguration:
|
|
263
|
+
issuer: https://cognito-idp.us-east-1.amazonaws.com/us-east-1_abc123
|
|
264
|
+
audience:
|
|
265
|
+
- my-client-id
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Supports any OIDC-compliant IdP (Cognito, Auth0, Okta, etc.).
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## Throttling and Quotas
|
|
273
|
+
|
|
274
|
+
### Throttling Hierarchy (Applied in Order)
|
|
275
|
+
|
|
276
|
+
```
|
|
277
|
+
Most specific → Least specific:
|
|
278
|
+
|
|
279
|
+
1. Per-client / per-method (usage plan + API key) ← REST only
|
|
280
|
+
2. Per-method (stage method settings)
|
|
281
|
+
3. Account-level (all APIs in account/Region)
|
|
282
|
+
4. AWS Regional (hard limit, not changeable)
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Token Bucket Algorithm
|
|
286
|
+
|
|
287
|
+
- Tokens added at steady-state rate (RPS)
|
|
288
|
+
- Bucket holds up to burst capacity
|
|
289
|
+
- Each request = 1 token
|
|
290
|
+
- Empty bucket → `429 Too Many Requests`
|
|
291
|
+
- Burst allows temporary spikes above steady-state
|
|
292
|
+
|
|
293
|
+
### Account-Level Defaults
|
|
294
|
+
|
|
295
|
+
| Quota | Default | Adjustable? |
|
|
296
|
+
|---|---|---|
|
|
297
|
+
| Steady-state RPS (per Region) | 10,000 | Yes |
|
|
298
|
+
| Burst capacity | 5,000 | Set by AWS based on RPS |
|
|
299
|
+
| Smaller Regions (Cape Town, Milan, Jakarta…) | 2,500 RPS / 1,250 burst | Yes |
|
|
300
|
+
|
|
301
|
+
### REST API Quotas
|
|
65
302
|
|
|
66
303
|
| Resource | Default | Adjustable? |
|
|
67
304
|
|---|---|---|
|
|
305
|
+
| Integration timeout | 50ms–29s (default 29s) | Yes (Regional/private only) |
|
|
306
|
+
| Payload size | 10 MB | No |
|
|
307
|
+
| Header value size | 10,240 bytes | No |
|
|
308
|
+
| Cache TTL | 0–3600s | No |
|
|
68
309
|
| Resources per API | 300 | Yes |
|
|
69
310
|
| Stages per API | 10 | Yes |
|
|
70
311
|
| API keys per account | 10,000 | No |
|
|
71
312
|
| Usage plans per account | 300 | Yes |
|
|
72
313
|
| Custom domains per Region | 120 | Yes |
|
|
73
|
-
| Header value size | 10,240 bytes | No |
|
|
74
|
-
| Cache TTL | 0–3600s | No |
|
|
75
314
|
| Mapping template size | 300 KB | No |
|
|
76
315
|
|
|
77
|
-
### HTTP API
|
|
316
|
+
### HTTP API Quotas
|
|
78
317
|
|
|
79
318
|
| Resource | Default | Adjustable? |
|
|
80
319
|
|---|---|---|
|
|
320
|
+
| Integration timeout | 30s max | No |
|
|
321
|
+
| Payload size | 10 MB | No |
|
|
81
322
|
| Routes per API | 300 | Yes |
|
|
82
323
|
| Stages per API | 10 | Yes |
|
|
83
324
|
| Integrations per API | 300 | No |
|
|
84
325
|
| Custom domains per Region | 120 | Yes |
|
|
85
326
|
| VPC links per Region | 10 | Yes |
|
|
86
327
|
|
|
87
|
-
|
|
328
|
+
### Usage Plans (REST API Only)
|
|
329
|
+
|
|
330
|
+
- Per-client rate limits (RPS) and burst limits via API keys
|
|
331
|
+
- Daily/weekly/monthly quotas per key
|
|
332
|
+
- Method-level throttling within a plan (e.g., `GET /pets` = 100 RPS)
|
|
333
|
+
|
|
334
|
+
### Client-Side 429 Handling
|
|
335
|
+
|
|
336
|
+
- Exponential backoff with jitter
|
|
337
|
+
- Respect `Retry-After` header
|
|
338
|
+
- Client-side rate limiting to stay under known limits
|
|
88
339
|
|
|
89
340
|
---
|
|
90
341
|
|
|
91
|
-
##
|
|
342
|
+
## WebSocket APIs
|
|
92
343
|
|
|
93
|
-
|
|
94
|
-
|---|---|---|
|
|
95
|
-
| Identity source | Single header (bearer token) | Headers, query strings, stage vars, `$context` |
|
|
96
|
-
| Cache key | Token header value | All specified identity sources combined |
|
|
97
|
-
| Available on | REST API only | REST API + HTTP API |
|
|
98
|
-
| Recommendation | Legacy | **Preferred for new APIs** |
|
|
344
|
+
### Route Architecture
|
|
99
345
|
|
|
100
|
-
|
|
346
|
+
```
|
|
347
|
+
Client connects → $connect (auth, store connectionId)
|
|
348
|
+
Client sends msg → route selection → custom route or $default
|
|
349
|
+
Server pushes data → @connections API (POST to connectionId)
|
|
350
|
+
Client disconnects → $disconnect (cleanup connectionId)
|
|
351
|
+
```
|
|
101
352
|
|
|
102
|
-
|
|
353
|
+
### Route Selection
|
|
103
354
|
|
|
104
|
-
|
|
355
|
+
- Expression: `$request.body.action` (routes on JSON `action` field)
|
|
356
|
+
- Non-JSON messages → always `$default`
|
|
105
357
|
|
|
106
|
-
|
|
358
|
+
### Predefined Routes
|
|
359
|
+
|
|
360
|
+
| Route | When | Required? | Notes |
|
|
361
|
+
|---|---|---|---|
|
|
362
|
+
| `$connect` | Connection initiated | No | Auth here; connection pending until integration completes |
|
|
363
|
+
| `$disconnect` | Connection closed | No | Best-effort; connection already closed |
|
|
364
|
+
| `$default` | No matching route / non-JSON | No | Catch-all fallback |
|
|
365
|
+
|
|
366
|
+
### Connection Management — Python
|
|
367
|
+
|
|
368
|
+
```python
|
|
369
|
+
import boto3, json
|
|
370
|
+
|
|
371
|
+
dynamodb = boto3.resource("dynamodb")
|
|
372
|
+
table = dynamodb.Table("WebSocketConnections")
|
|
373
|
+
|
|
374
|
+
def connect_handler(event, context):
|
|
375
|
+
table.put_item(Item={"connectionId": event["requestContext"]["connectionId"]})
|
|
376
|
+
return {"statusCode": 200, "body": "Connected"}
|
|
377
|
+
|
|
378
|
+
def send_to_client(endpoint_url, connection_id, data):
|
|
379
|
+
client = boto3.client("apigatewaymanagementapi", endpoint_url=endpoint_url)
|
|
380
|
+
client.post_to_connection(
|
|
381
|
+
ConnectionId=connection_id,
|
|
382
|
+
Data=json.dumps(data).encode("utf-8"),
|
|
383
|
+
)
|
|
384
|
+
```
|
|
107
385
|
|
|
108
|
-
|
|
386
|
+
### Connection Management — TypeScript
|
|
109
387
|
|
|
110
|
-
|
|
388
|
+
```typescript
|
|
389
|
+
import { ApiGatewayManagementApiClient, PostToConnectionCommand } from "@aws-sdk/client-apigatewaymanagementapi";
|
|
390
|
+
|
|
391
|
+
async function sendToClient(endpoint: string, connectionId: string, data: object) {
|
|
392
|
+
const client = new ApiGatewayManagementApiClient({ endpoint });
|
|
393
|
+
await client.send(new PostToConnectionCommand({
|
|
394
|
+
ConnectionId: connectionId,
|
|
395
|
+
Data: Buffer.from(JSON.stringify(data)),
|
|
396
|
+
}));
|
|
397
|
+
}
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
### WebSocket Quotas
|
|
401
|
+
|
|
402
|
+
| Resource | Limit |
|
|
111
403
|
|---|---|
|
|
112
404
|
| Idle connection timeout | 10 minutes |
|
|
113
405
|
| Max connection duration | 2 hours |
|
|
114
406
|
| Message payload | 128 KB (hard limit) |
|
|
115
407
|
|
|
116
|
-
|
|
408
|
+
### WebSocket Close Codes
|
|
117
409
|
|
|
118
|
-
|
|
410
|
+
| Code | Meaning |
|
|
411
|
+
|---|---|
|
|
412
|
+
| 1001 | Idle timeout or max duration exceeded |
|
|
413
|
+
| 1003 | Unsupported binary media type |
|
|
414
|
+
| 1005 | No status code present (reserved, not sent on wire) |
|
|
415
|
+
| 1006 | Abnormal closure — no close frame received |
|
|
416
|
+
| 1008 | Throttled (too many requests) |
|
|
417
|
+
| 1009 | Message exceeds size limit |
|
|
418
|
+
| 1011 | Internal server error |
|
|
419
|
+
| 1012 | Service restart |
|
|
119
420
|
|
|
120
421
|
---
|
|
121
422
|
|
|
122
|
-
##
|
|
423
|
+
## 502/504 Debugging
|
|
123
424
|
|
|
124
|
-
|
|
425
|
+
### 502 Bad Gateway — Flowchart
|
|
125
426
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
427
|
+
```
|
|
428
|
+
502 Bad Gateway
|
|
429
|
+
│
|
|
430
|
+
├─ Lambda proxy integration?
|
|
431
|
+
│ └─ YES → Check response format (most common cause):
|
|
432
|
+
│ ├─ statusCode: integer (string is coerced, missing defaults to 200)
|
|
433
|
+
│ ├─ headers: object with string values
|
|
434
|
+
│ ├─ body: string (JSON.stringify, not raw object)
|
|
435
|
+
│ └─ Unhandled exception? → Check CloudWatch Logs
|
|
436
|
+
│
|
|
437
|
+
├─ Lambda authorizer?
|
|
438
|
+
│ ├─ Must return valid IAM policy format
|
|
439
|
+
│ ├─ Check authorizer Lambda logs
|
|
440
|
+
│ └─ Authorizer timeout is separate from integration timeout
|
|
441
|
+
│
|
|
442
|
+
├─ HTTP integration?
|
|
443
|
+
│ ├─ Backend reachable from API Gateway?
|
|
444
|
+
│ ├─ Valid HTTP response from backend?
|
|
445
|
+
│ └─ VPC link healthy? (private integration)
|
|
446
|
+
│
|
|
447
|
+
└─ Other causes:
|
|
448
|
+
├─ Payload > 10 MB
|
|
449
|
+
├─ Binary media types */* (breaks OPTIONS)
|
|
450
|
+
└─ Stage variable → wrong Lambda alias
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
### Correct Lambda Response Format
|
|
454
|
+
|
|
455
|
+
The **most common cause of 502** is an incorrect response format in Lambda proxy integrations.
|
|
456
|
+
|
|
457
|
+
**Python — Correct:**
|
|
458
|
+
|
|
459
|
+
```python
|
|
460
|
+
def handler(event, context):
|
|
461
|
+
return {
|
|
462
|
+
"isBase64Encoded": False, # boolean
|
|
463
|
+
"statusCode": 200, # integer, NOT string
|
|
464
|
+
"headers": { # object with string values
|
|
465
|
+
"Content-Type": "application/json",
|
|
466
|
+
},
|
|
467
|
+
"body": json.dumps({"key": "val"}) # MUST be string
|
|
468
|
+
}
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
**TypeScript — Correct:**
|
|
472
|
+
|
|
473
|
+
```typescript
|
|
474
|
+
export const handler = async (event: any) => ({
|
|
475
|
+
isBase64Encoded: false,
|
|
476
|
+
statusCode: 200,
|
|
477
|
+
headers: { "Content-Type": "application/json" },
|
|
478
|
+
body: JSON.stringify({ key: "val" }), // MUST be string
|
|
479
|
+
});
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
**Common mistakes -> 502:**
|
|
483
|
+
|
|
484
|
+
```python
|
|
485
|
+
return {"statusCode": 200, "body": {"key": "val"}} # body not a string -> 502
|
|
486
|
+
return "just a string" # not a JSON object -> 502
|
|
487
|
+
# Note: string statusCode ("200") and missing statusCode are silently handled (no 502)
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
### 504 Timeout — Flowchart
|
|
491
|
+
|
|
492
|
+
```
|
|
493
|
+
504 Endpoint Request Timed Out
|
|
494
|
+
│
|
|
495
|
+
├─ Step 1: Enable CloudWatch logging
|
|
496
|
+
│ ├─ REST: execution logs + access logs
|
|
497
|
+
│ ├─ HTTP: access logs only
|
|
498
|
+
│ └─ Include: $context.integrationLatency, $context.integration.status
|
|
499
|
+
│
|
|
500
|
+
├─ Step 2: Identify timeout source
|
|
501
|
+
│ ├─ REST API: integration timeout configurable 50ms–29s
|
|
502
|
+
│ ├─ HTTP API: 30s max (can be lowered, cannot be raised)
|
|
503
|
+
│ └─ Was integration invoked?
|
|
504
|
+
│ ├─ NO → Transient network failure; retry
|
|
505
|
+
│ └─ YES → Backend too slow
|
|
506
|
+
│
|
|
507
|
+
├─ Step 3: Reduce integration runtime
|
|
508
|
+
│ ├─ Move non-critical work to async (SQS, Step Functions)
|
|
509
|
+
│ ├─ Increase Lambda memory (faster CPU)
|
|
510
|
+
│ ├─ Provisioned concurrency (eliminate cold starts)
|
|
511
|
+
│ └─ Check downstream dependencies (DB, external APIs)
|
|
512
|
+
│
|
|
513
|
+
└─ Step 4: Increase timeout (REST only)
|
|
514
|
+
├─ Request via Service Quotas console
|
|
515
|
+
├─ Update integration timeout value AND redeploy
|
|
516
|
+
└─ Note: may reduce account throttle quota
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
### CloudWatch Insights Queries
|
|
520
|
+
|
|
521
|
+
**Find all 5xx errors:**
|
|
522
|
+
|
|
523
|
+
```
|
|
524
|
+
fields @timestamp, @message, @logStream
|
|
525
|
+
| filter status >= 500 and status < 600
|
|
526
|
+
| sort @timestamp desc
|
|
527
|
+
| display @timestamp, httpMethod, resourcePath, status, requestId
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
**Find timeout errors:**
|
|
531
|
+
|
|
532
|
+
```
|
|
533
|
+
fields @timestamp, @message
|
|
534
|
+
| filter @message like "Execution failed due to a timeout error"
|
|
535
|
+
| sort @timestamp desc
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
**Find slow integrations (>10s):**
|
|
539
|
+
|
|
540
|
+
```
|
|
541
|
+
fields @timestamp, integrationLatency, status, resourcePath
|
|
542
|
+
| filter integrationLatency > 10000
|
|
543
|
+
| sort integrationLatency desc
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
### Automated Troubleshooting
|
|
547
|
+
|
|
548
|
+
**AWSSupport-TroubleshootAPIGatewayHttpErrors** — Systems Manager runbook:
|
|
132
549
|
|
|
133
|
-
|
|
550
|
+
- Validates API, resource, operation, and stage
|
|
551
|
+
- Analyzes CloudWatch logs automatically
|
|
552
|
+
- Requires: `apigateway:GET`, `logs:GetQueryResults`, `logs:StartQuery`, `ssm:*`
|
|
553
|
+
- Available in Systems Manager console → Automation
|