Claude Skill

api-gateway

AWS API Gateway for REST and HTTP API management. Use when creating APIs, configuring integrations, setting up authorization, managing stages, implementing rate limiting, or troubleshooting API issues.

LLM Mart · 0 points · 0 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download itsmostafa-aws-agent-skills-skills_api-gateway-e786d25.zip · 5 KB
Part of itsmostafa/aws-agent-skills — 17 skills

Install

skills CLI npx skills add https://github.com/itsmostafa/aws-agent-skills/tree/main/skills/api-gateway
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install itsmostafa-aws-agent-skills@llmmart
Git git clone https://github.com/itsmostafa/aws-agent-skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole itsmostafa/aws-agent-skills collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

AWS API Gateway

Amazon API Gateway is a fully managed service for creating, publishing, and securing APIs at any scale. Supports REST APIs, HTTP APIs, and WebSocket APIs.

Table of Contents

Core Concepts

API Types

Type Description Use Case
HTTP API Low-latency, cost-effective Simple APIs, Lambda proxy
REST API Full-featured, more control Complex APIs, transformation
WebSocket API Bidirectional communication Real-time apps, chat

Key Components

  • Resources: URL paths (/users, /orders/)
  • Methods: HTTP verbs (GET, POST, PUT, DELETE)
  • Integrations: Backend connections (Lambda, HTTP, AWS services)
  • Stages: Deployment environments (dev, prod)

Integration Types

Type Description
Lambda Proxy Pass-through to Lambda (recommended)
Lambda Custom Transform request/response
HTTP Proxy Pass-through to HTTP endpoint
AWS Service Direct integration with AWS services
Mock Return static response

Common Patterns

Create HTTP API with Lambda

AWS CLI:

# Create HTTP API
aws apigatewayv2 create-api \
  --name my-api \
  --protocol-type HTTP \
  --target arn:aws:lambda:us-east-1:123456789012:function:MyFunction

# Get API endpoint
aws apigatewayv2 get-api --api-id abc123 --query 'ApiEndpoint'

SAM Template:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Resources:
  MyApi:
    Type: AWS::Serverless::HttpApi
    Properties:
      StageName: prod

  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: app.handler
      Runtime: python3.12
      Events:
        ApiEvent:
          Type: HttpApi
          Properties:
            ApiId: !Ref MyApi
            Path: /items
            Method: GET

Create REST API with Lambda Proxy

# Create REST API
aws apigateway create-rest-api \
  --name my-rest-api \
  --endpoint-configuration types=REGIONAL

API_ID=abc123

# Get root resource ID
ROOT_ID=$(aws apigateway get-resources --rest-api-id $API_ID --query 'items[0].id' --output text)

# Create resource
aws apigateway create-resource \
  --rest-api-id $API_ID \
  --parent-id $ROOT_ID \
  --path-part items

RESOURCE_ID=xyz789

# Create method
aws apigateway put-method \
  --rest-api-id $API_ID \
  --resource-id $RESOURCE_ID \
  --http-method GET \
  --authorization-type NONE

# Create Lambda integration
aws apigateway put-integration \
  --rest-api-id $API_ID \
  --resource-id $RESOURCE_ID \
  --http-method GET \
  --type AWS_PROXY \
  --integration-http-method POST \
  --uri arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:MyFunction/invocations

# Deploy to stage
aws apigateway create-deployment \
  --rest-api-id $API_ID \
  --stage-name prod

Lambda Handler for API Gateway

import json

def handler(event, context):
    # HTTP API event
    http_method = event.get('requestContext', {}).get('http', {}).get('method')
    path = event.get('rawPath', '')
    query_params = event.get('queryStringParameters', {})
    body = event.get('body', '')

    if body and event.get('isBase64Encoded'):
        import base64
        body = base64.b64decode(body).decode('utf-8')

    # Process request
    response_body = {'message': 'Success', 'path': path}

    return {
        'statusCode': 200,
        'headers': {
            'Content-Type': 'application/json'
        },
        'body': json.dumps(response_body)
    }

Configure CORS

HTTP API:

aws apigatewayv2 update-api \
  --api-id abc123 \
  --cors-configuration '{
    "AllowOrigins": ["https://example.com"],
    "AllowMethods": ["GET", "POST", "PUT", "DELETE"],
    "AllowHeaders": ["Content-Type", "Authorization"],
    "MaxAge": 86400
  }'

REST API:

# Enable CORS on resource
aws apigateway put-method \
  --rest-api-id $API_ID \
  --resource-id $RESOURCE_ID \
  --http-method OPTIONS \
  --authorization-type NONE

aws apigateway put-integration \
  --rest-api-id $API_ID \
  --resource-id $RESOURCE_ID \
  --http-method OPTIONS \
  --type MOCK \
  --request-templates '{"application/json": "{\"statusCode\": 200}"}'

aws apigateway put-method-response \
  --rest-api-id $API_ID \
  --resource-id $RESOURCE_ID \
  --http-method OPTIONS \
  --status-code 200 \
  --response-parameters '{
    "method.response.header.Access-Control-Allow-Headers": true,
    "method.response.header.Access-Control-Allow-Methods": true,
    "method.response.header.Access-Control-Allow-Origin": true
  }'

aws apigateway put-integration-response \
  --rest-api-id $API_ID \
  --resource-id $RESOURCE_ID \
  --http-method OPTIONS \
  --status-code 200 \
  --response-parameters '{
    "method.response.header.Access-Control-Allow-Headers": "'\''Content-Type,Authorization'\''",
    "method.response.header.Access-Control-Allow-Methods": "'\''GET,POST,PUT,DELETE,OPTIONS'\''",
    "method.response.header.Access-Control-Allow-Origin": "'\''*'\''"
  }'

JWT Authorization (HTTP API)

aws apigatewayv2 create-authorizer \
  --api-id abc123 \
  --name jwt-authorizer \
  --authorizer-type JWT \
  --identity-source '$request.header.Authorization' \
  --jwt-configuration '{
    "Issuer": "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_abc123",
    "Audience": ["client-id"]
  }'

CLI Reference

HTTP API (apigatewayv2)

Command Description
aws apigatewayv2 create-api Create API
aws apigatewayv2 get-apis List APIs
aws apigatewayv2 create-route Create route
aws apigatewayv2 create-integration Create integration
aws apigatewayv2 create-stage Create stage
aws apigatewayv2 create-authorizer Create authorizer

REST API (apigateway)

Command Description
aws apigateway create-rest-api Create API
aws apigateway get-rest-apis List APIs
aws apigateway create-resource Create resource
aws apigateway put-method Create method
aws apigateway put-integration Create integration
aws apigateway create-deployment Deploy API

Best Practices

Performance

  • Use HTTP APIs for simple use cases (70% cheaper, lower latency)
  • Enable caching for REST APIs
  • Use regional endpoints unless global distribution needed
  • Implement pagination for list endpoints

Security

  • Use authorization on all endpoints
  • Enable WAF for REST APIs
  • Use API keys for rate limiting (not authentication)
  • Enable access logging
  • Use HTTPS only

Reliability

  • Set up throttling to protect backends
  • Configure timeout appropriately
  • Use canary deployments for updates
  • Monitor with CloudWatch

Troubleshooting

403 Forbidden

Causes:

  • Missing authorization
  • Invalid API key
  • WAF blocking
  • Resource policy denying

Debug:

# Check API key
aws apigateway get-api-key --api-key abc123 --include-value

# Check authorizer
aws apigatewayv2 get-authorizer --api-id abc123 --authorizer-id xyz789

502 Bad Gateway

Causes:

  • Lambda error
  • Integration timeout
  • Invalid response format

Lambda response format:

# Correct format
return {
    'statusCode': 200,
    'headers': {'Content-Type': 'application/json'},
    'body': json.dumps({'message': 'success'})
}

# Wrong - missing statusCode
return {'message': 'success'}

504 Gateway Timeout

Causes:

  • Backend timeout (Lambda max 29 seconds for REST API)
  • Integration timeout too short

Solutions:

  • Increase Lambda timeout
  • Use async processing for long operations
  • Increase integration timeout (max 29s for REST, 30s for HTTP)

CORS Errors

Debug:

  • Check OPTIONS method exists
  • Verify headers in response
  • Check origin matches allowed origins

References

Files (aws-agent-skills)
  • integration-patterns.md 9 KB
    # API Gateway Integration Patterns
    
    Advanced integration patterns and configurations.
    
    ## Lambda Integrations
    
    ### Proxy Integration (Recommended)
    
    Pass entire request to Lambda:
    
    ```yaml
    # SAM
    Resources:
      GetItemsFunction:
        Type: AWS::Serverless::Function
        Properties:
          Handler: app.handler
          Events:
            GetItems:
              Type: Api
              Properties:
                Path: /items
                Method: GET
    ```
    
    Lambda receives:
    
    ```json
    {
      "resource": "/items",
      "path": "/items",
      "httpMethod": "GET",
      "headers": {...},
      "queryStringParameters": {...},
      "pathParameters": {...},
      "body": "...",
      "isBase64Encoded": false
    }
    ```
    
    ### Custom Integration
    
    Transform request/response:
    
    ```bash
    # Request template
    aws apigateway put-integration \
      --rest-api-id $API_ID \
      --resource-id $RESOURCE_ID \
      --http-method POST \
      --type AWS \
      --integration-http-method POST \
      --uri arn:aws:apigateway:us-east-1:lambda:path/... \
      --request-templates '{
        "application/json": "{\"action\": \"$input.params(\"action\")\", \"data\": $input.json(\"$.body\")}"
      }'
    
    # Response template
    aws apigateway put-integration-response \
      --rest-api-id $API_ID \
      --resource-id $RESOURCE_ID \
      --http-method POST \
      --status-code 200 \
      --response-templates '{
        "application/json": "{\"result\": $input.json(\"$.Payload\")}"
      }'
    ```
    
    ## AWS Service Integrations
    
    ### Direct DynamoDB Integration
    
    ```json
    {
      "type": "AWS",
      "uri": "arn:aws:apigateway:us-east-1:dynamodb:action/GetItem",
      "credentials": "arn:aws:iam::123456789012:role/apigw-dynamodb-role",
      "requestTemplates": {
        "application/json": "{\"TableName\": \"Users\", \"Key\": {\"id\": {\"S\": \"$input.params('id')\"}}}"
      },
      "responses": {
        "default": {
          "statusCode": "200",
          "responseTemplates": {
            "application/json": "#set($item = $input.path('$.Item'))\n{\"id\": \"$item.id.S\", \"name\": \"$item.name.S\"}"
          }
        }
      }
    }
    ```
    
    ### Direct SQS Integration
    
    ```json
    {
      "type": "AWS",
      "uri": "arn:aws:apigateway:us-east-1:sqs:path/123456789012/my-queue",
      "credentials": "arn:aws:iam::123456789012:role/apigw-sqs-role",
      "requestParameters": {
        "integration.request.header.Content-Type": "'application/x-www-form-urlencoded'"
      },
      "requestTemplates": {
        "application/json": "Action=SendMessage&MessageBody=$util.urlEncode($input.body)"
      },
      "responses": {
        "default": {
          "statusCode": "200",
          "responseTemplates": {
            "application/json": "{\"messageId\": \"$input.path('$.SendMessageResponse.SendMessageResult.MessageId')\"}"
          }
        }
      }
    }
    ```
    
    ### Direct Step Functions Integration
    
    ```json
    {
      "type": "AWS",
      "uri": "arn:aws:apigateway:us-east-1:states:action/StartExecution",
      "credentials": "arn:aws:iam::123456789012:role/apigw-stepfunctions-role",
      "requestTemplates": {
        "application/json": "{\"input\": \"$util.escapeJavaScript($input.json('$'))\", \"stateMachineArn\": \"arn:aws:states:us-east-1:123456789012:stateMachine:MyWorkflow\"}"
      }
    }
    ```
    
    ## HTTP Integrations
    
    ### HTTP Proxy
    
    ```bash
    aws apigateway put-integration \
      --rest-api-id $API_ID \
      --resource-id $RESOURCE_ID \
      --http-method GET \
      --type HTTP_PROXY \
      --integration-http-method GET \
      --uri https://api.example.com/items
    ```
    
    ### HTTP with VPC Link
    
    ```bash
    # Create VPC Link
    aws apigateway create-vpc-link \
      --name my-vpc-link \
      --target-arns arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/net/my-nlb/abc123
    
    # Use VPC Link in integration
    aws apigateway put-integration \
      --rest-api-id $API_ID \
      --resource-id $RESOURCE_ID \
      --http-method GET \
      --type HTTP_PROXY \
      --connection-type VPC_LINK \
      --connection-id vpc-link-id \
      --uri http://my-nlb.internal:8080/items
    ```
    
    ## Request Validation
    
    ### Enable Request Validation
    
    ```bash
    # Create validator
    aws apigateway create-request-validator \
      --rest-api-id $API_ID \
      --name body-validator \
      --validate-request-body \
      --validate-request-parameters
    
    # Create model
    aws apigateway create-model \
      --rest-api-id $API_ID \
      --name CreateUserModel \
      --content-type application/json \
      --schema '{
        "type": "object",
        "required": ["name", "email"],
        "properties": {
          "name": {"type": "string", "minLength": 1},
          "email": {"type": "string", "format": "email"}
        }
      }'
    
    # Apply to method
    aws apigateway put-method \
      --rest-api-id $API_ID \
      --resource-id $RESOURCE_ID \
      --http-method POST \
      --authorization-type NONE \
      --request-validator-id validator-id \
      --request-models '{"application/json": "CreateUserModel"}'
    ```
    
    ## Authorization
    
    ### Cognito Authorizer (REST API)
    
    ```bash
    aws apigateway create-authorizer \
      --rest-api-id $API_ID \
      --name cognito-authorizer \
      --type COGNITO_USER_POOLS \
      --identity-source 'method.request.header.Authorization' \
      --provider-arns arn:aws:cognito-idp:us-east-1:123456789012:userpool/us-east-1_abc123
    ```
    
    ### Lambda Authorizer
    
    ```bash
    aws apigateway create-authorizer \
      --rest-api-id $API_ID \
      --name custom-authorizer \
      --type TOKEN \
      --authorizer-uri arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:Authorizer/invocations \
      --identity-source 'method.request.header.Authorization' \
      --authorizer-result-ttl-in-seconds 300
    ```
    
    Lambda authorizer code:
    
    ```python
    def handler(event, context):
        token = event['authorizationToken']
        method_arn = event['methodArn']
    
        # Validate token
        if is_valid_token(token):
            principal_id = get_user_id(token)
            return generate_policy(principal_id, 'Allow', method_arn)
        else:
            raise Exception('Unauthorized')
    
    def generate_policy(principal_id, effect, resource):
        return {
            'principalId': principal_id,
            'policyDocument': {
                'Version': '2012-10-17',
                'Statement': [{
                    'Action': 'execute-api:Invoke',
                    'Effect': effect,
                    'Resource': resource
                }]
            },
            'context': {
                'userId': principal_id
            }
        }
    ```
    
    ## Rate Limiting
    
    ### Usage Plans and API Keys
    
    ```bash
    # Create API key
    aws apigateway create-api-key \
      --name client-api-key \
      --enabled
    
    # Create usage plan
    aws apigateway create-usage-plan \
      --name basic-plan \
      --throttle burstLimit=100,rateLimit=50 \
      --quota limit=10000,period=MONTH \
      --api-stages apiId=$API_ID,stage=prod
    
    # Associate key with plan
    aws apigateway create-usage-plan-key \
      --usage-plan-id plan-id \
      --key-id key-id \
      --key-type API_KEY
    ```
    
    ### Method-Level Throttling
    
    ```bash
    aws apigateway update-stage \
      --rest-api-id $API_ID \
      --stage-name prod \
      --patch-operations '[{
        "op": "replace",
        "path": "/~1items/GET/throttling/burstLimit",
        "value": "50"
      }, {
        "op": "replace",
        "path": "/~1items/GET/throttling/rateLimit",
        "value": "100"
      }]'
    ```
    
    ## Caching (REST API)
    
    ### Enable Caching
    
    ```bash
    aws apigateway update-stage \
      --rest-api-id $API_ID \
      --stage-name prod \
      --patch-operations '[{
        "op": "replace",
        "path": "/cacheClusterEnabled",
        "value": "true"
      }, {
        "op": "replace",
        "path": "/cacheClusterSize",
        "value": "0.5"
      }]'
    ```
    
    ### Cache Key Parameters
    
    ```bash
    aws apigateway update-method \
      --rest-api-id $API_ID \
      --resource-id $RESOURCE_ID \
      --http-method GET \
      --patch-operations '[{
        "op": "replace",
        "path": "/requestParameters/method.request.querystring.category",
        "value": "true"
      }]'
    ```
    
    ### Cache Invalidation
    
    ```bash
    # From client with API key
    curl -X GET "https://api.example.com/prod/items" \
      -H "Cache-Control: max-age=0"
    ```
    
    ## Logging and Monitoring
    
    ### Access Logging
    
    ```bash
    # Create log group
    aws logs create-log-group --log-group-name API-Gateway-Access-Logs
    
    # Enable access logging
    aws apigateway update-stage \
      --rest-api-id $API_ID \
      --stage-name prod \
      --patch-operations '[{
        "op": "replace",
        "path": "/accessLogSettings/destinationArn",
        "value": "arn:aws:logs:us-east-1:123456789012:log-group:API-Gateway-Access-Logs"
      }, {
        "op": "replace",
        "path": "/accessLogSettings/format",
        "value": "{\"requestId\":\"$context.requestId\",\"ip\":\"$context.identity.sourceIp\",\"method\":\"$context.httpMethod\",\"path\":\"$context.path\",\"status\":\"$context.status\",\"latency\":\"$context.responseLatency\"}"
      }]'
    ```
    
    ### Execution Logging
    
    ```bash
    aws apigateway update-stage \
      --rest-api-id $API_ID \
      --stage-name prod \
      --patch-operations '[{
        "op": "replace",
        "path": "/*/*/logging/loglevel",
        "value": "INFO"
      }, {
        "op": "replace",
        "path": "/*/*/logging/dataTrace",
        "value": "true"
      }]'
    ```
    
    ## Canary Deployments
    
    ```bash
    # Create canary
    aws apigateway update-stage \
      --rest-api-id $API_ID \
      --stage-name prod \
      --patch-operations '[{
        "op": "replace",
        "path": "/canarySettings/percentTraffic",
        "value": "10"
      }, {
        "op": "replace",
        "path": "/canarySettings/deploymentId",
        "value": "new-deployment-id"
      }]'
    
    # Promote canary
    aws apigateway update-stage \
      --rest-api-id $API_ID \
      --stage-name prod \
      --patch-operations '[{
        "op": "remove",
        "path": "/canarySettings"
      }]'
    ```
    
  • SKILL.md 8.7 KB
    ---
    name: api-gateway
    description: AWS API Gateway for REST and HTTP API management. Use when creating APIs, configuring integrations, setting up authorization, managing stages, implementing rate limiting, or troubleshooting API issues.
    last_updated: "2026-01-07"
    doc_source: https://docs.aws.amazon.com/apigateway/latest/developerguide/
    ---
    
    # AWS API Gateway
    
    Amazon API Gateway is a fully managed service for creating, publishing, and securing APIs at any scale. Supports REST APIs, HTTP APIs, and WebSocket APIs.
    
    ## Table of Contents
    
    - [Core Concepts](#core-concepts)
    - [Common Patterns](#common-patterns)
    - [CLI Reference](#cli-reference)
    - [Best Practices](#best-practices)
    - [Troubleshooting](#troubleshooting)
    - [References](#references)
    
    ## Core Concepts
    
    ### API Types
    
    | Type | Description | Use Case |
    |------|-------------|----------|
    | **HTTP API** | Low-latency, cost-effective | Simple APIs, Lambda proxy |
    | **REST API** | Full-featured, more control | Complex APIs, transformation |
    | **WebSocket API** | Bidirectional communication | Real-time apps, chat |
    
    ### Key Components
    
    - **Resources**: URL paths (/users, /orders/{id})
    - **Methods**: HTTP verbs (GET, POST, PUT, DELETE)
    - **Integrations**: Backend connections (Lambda, HTTP, AWS services)
    - **Stages**: Deployment environments (dev, prod)
    
    ### Integration Types
    
    | Type | Description |
    |------|-------------|
    | **Lambda Proxy** | Pass-through to Lambda (recommended) |
    | **Lambda Custom** | Transform request/response |
    | **HTTP Proxy** | Pass-through to HTTP endpoint |
    | **AWS Service** | Direct integration with AWS services |
    | **Mock** | Return static response |
    
    ## Common Patterns
    
    ### Create HTTP API with Lambda
    
    **AWS CLI:**
    
    ```bash
    # Create HTTP API
    aws apigatewayv2 create-api \
      --name my-api \
      --protocol-type HTTP \
      --target arn:aws:lambda:us-east-1:123456789012:function:MyFunction
    
    # Get API endpoint
    aws apigatewayv2 get-api --api-id abc123 --query 'ApiEndpoint'
    ```
    
    **SAM Template:**
    
    ```yaml
    AWSTemplateFormatVersion: '2010-09-09'
    Transform: AWS::Serverless-2016-10-31
    
    Resources:
      MyApi:
        Type: AWS::Serverless::HttpApi
        Properties:
          StageName: prod
    
      MyFunction:
        Type: AWS::Serverless::Function
        Properties:
          Handler: app.handler
          Runtime: python3.12
          Events:
            ApiEvent:
              Type: HttpApi
              Properties:
                ApiId: !Ref MyApi
                Path: /items
                Method: GET
    ```
    
    ### Create REST API with Lambda Proxy
    
    ```bash
    # Create REST API
    aws apigateway create-rest-api \
      --name my-rest-api \
      --endpoint-configuration types=REGIONAL
    
    API_ID=abc123
    
    # Get root resource ID
    ROOT_ID=$(aws apigateway get-resources --rest-api-id $API_ID --query 'items[0].id' --output text)
    
    # Create resource
    aws apigateway create-resource \
      --rest-api-id $API_ID \
      --parent-id $ROOT_ID \
      --path-part items
    
    RESOURCE_ID=xyz789
    
    # Create method
    aws apigateway put-method \
      --rest-api-id $API_ID \
      --resource-id $RESOURCE_ID \
      --http-method GET \
      --authorization-type NONE
    
    # Create Lambda integration
    aws apigateway put-integration \
      --rest-api-id $API_ID \
      --resource-id $RESOURCE_ID \
      --http-method GET \
      --type AWS_PROXY \
      --integration-http-method POST \
      --uri arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:MyFunction/invocations
    
    # Deploy to stage
    aws apigateway create-deployment \
      --rest-api-id $API_ID \
      --stage-name prod
    ```
    
    ### Lambda Handler for API Gateway
    
    ```python
    import json
    
    def handler(event, context):
        # HTTP API event
        http_method = event.get('requestContext', {}).get('http', {}).get('method')
        path = event.get('rawPath', '')
        query_params = event.get('queryStringParameters', {})
        body = event.get('body', '')
    
        if body and event.get('isBase64Encoded'):
            import base64
            body = base64.b64decode(body).decode('utf-8')
    
        # Process request
        response_body = {'message': 'Success', 'path': path}
    
        return {
            'statusCode': 200,
            'headers': {
                'Content-Type': 'application/json'
            },
            'body': json.dumps(response_body)
        }
    ```
    
    ### Configure CORS
    
    **HTTP API:**
    
    ```bash
    aws apigatewayv2 update-api \
      --api-id abc123 \
      --cors-configuration '{
        "AllowOrigins": ["https://example.com"],
        "AllowMethods": ["GET", "POST", "PUT", "DELETE"],
        "AllowHeaders": ["Content-Type", "Authorization"],
        "MaxAge": 86400
      }'
    ```
    
    **REST API:**
    
    ```bash
    # Enable CORS on resource
    aws apigateway put-method \
      --rest-api-id $API_ID \
      --resource-id $RESOURCE_ID \
      --http-method OPTIONS \
      --authorization-type NONE
    
    aws apigateway put-integration \
      --rest-api-id $API_ID \
      --resource-id $RESOURCE_ID \
      --http-method OPTIONS \
      --type MOCK \
      --request-templates '{"application/json": "{\"statusCode\": 200}"}'
    
    aws apigateway put-method-response \
      --rest-api-id $API_ID \
      --resource-id $RESOURCE_ID \
      --http-method OPTIONS \
      --status-code 200 \
      --response-parameters '{
        "method.response.header.Access-Control-Allow-Headers": true,
        "method.response.header.Access-Control-Allow-Methods": true,
        "method.response.header.Access-Control-Allow-Origin": true
      }'
    
    aws apigateway put-integration-response \
      --rest-api-id $API_ID \
      --resource-id $RESOURCE_ID \
      --http-method OPTIONS \
      --status-code 200 \
      --response-parameters '{
        "method.response.header.Access-Control-Allow-Headers": "'\''Content-Type,Authorization'\''",
        "method.response.header.Access-Control-Allow-Methods": "'\''GET,POST,PUT,DELETE,OPTIONS'\''",
        "method.response.header.Access-Control-Allow-Origin": "'\''*'\''"
      }'
    ```
    
    ### JWT Authorization (HTTP API)
    
    ```bash
    aws apigatewayv2 create-authorizer \
      --api-id abc123 \
      --name jwt-authorizer \
      --authorizer-type JWT \
      --identity-source '$request.header.Authorization' \
      --jwt-configuration '{
        "Issuer": "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_abc123",
        "Audience": ["client-id"]
      }'
    ```
    
    ## CLI Reference
    
    ### HTTP API (apigatewayv2)
    
    | Command | Description |
    |---------|-------------|
    | `aws apigatewayv2 create-api` | Create API |
    | `aws apigatewayv2 get-apis` | List APIs |
    | `aws apigatewayv2 create-route` | Create route |
    | `aws apigatewayv2 create-integration` | Create integration |
    | `aws apigatewayv2 create-stage` | Create stage |
    | `aws apigatewayv2 create-authorizer` | Create authorizer |
    
    ### REST API (apigateway)
    
    | Command | Description |
    |---------|-------------|
    | `aws apigateway create-rest-api` | Create API |
    | `aws apigateway get-rest-apis` | List APIs |
    | `aws apigateway create-resource` | Create resource |
    | `aws apigateway put-method` | Create method |
    | `aws apigateway put-integration` | Create integration |
    | `aws apigateway create-deployment` | Deploy API |
    
    ## Best Practices
    
    ### Performance
    
    - **Use HTTP APIs** for simple use cases (70% cheaper, lower latency)
    - **Enable caching** for REST APIs
    - **Use regional endpoints** unless global distribution needed
    - **Implement pagination** for list endpoints
    
    ### Security
    
    - **Use authorization** on all endpoints
    - **Enable WAF** for REST APIs
    - **Use API keys** for rate limiting (not authentication)
    - **Enable access logging**
    - **Use HTTPS only**
    
    ### Reliability
    
    - **Set up throttling** to protect backends
    - **Configure timeout** appropriately
    - **Use canary deployments** for updates
    - **Monitor with CloudWatch**
    
    ## Troubleshooting
    
    ### 403 Forbidden
    
    **Causes:**
    - Missing authorization
    - Invalid API key
    - WAF blocking
    - Resource policy denying
    
    **Debug:**
    
    ```bash
    # Check API key
    aws apigateway get-api-key --api-key abc123 --include-value
    
    # Check authorizer
    aws apigatewayv2 get-authorizer --api-id abc123 --authorizer-id xyz789
    ```
    
    ### 502 Bad Gateway
    
    **Causes:**
    - Lambda error
    - Integration timeout
    - Invalid response format
    
    **Lambda response format:**
    
    ```python
    # Correct format
    return {
        'statusCode': 200,
        'headers': {'Content-Type': 'application/json'},
        'body': json.dumps({'message': 'success'})
    }
    
    # Wrong - missing statusCode
    return {'message': 'success'}
    ```
    
    ### 504 Gateway Timeout
    
    **Causes:**
    - Backend timeout (Lambda max 29 seconds for REST API)
    - Integration timeout too short
    
    **Solutions:**
    - Increase Lambda timeout
    - Use async processing for long operations
    - Increase integration timeout (max 29s for REST, 30s for HTTP)
    
    ### CORS Errors
    
    **Debug:**
    - Check OPTIONS method exists
    - Verify headers in response
    - Check origin matches allowed origins
    
    ## References
    
    - [API Gateway Developer Guide](https://docs.aws.amazon.com/apigateway/latest/developerguide/)
    - [API Gateway REST API Reference](https://docs.aws.amazon.com/apigateway/latest/api/)
    - [API Gateway CLI Reference](https://docs.aws.amazon.com/cli/latest/reference/apigateway/)
    - [boto3 API Gateway](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/apigateway.html)
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related