--- name: serverless-api description: Build and deploy a serverless HTTP API on AWS using AWS Lambda behind Amazon API Gateway. Use when the user asks to create a REST or HTTP API, connect a Lambda function to API Gateway, deploy a serverless endpoint or backend, or scaffold a serverless application. Provides an infrastructure-as-code walkthrough (AWS SAM and AWS CDK) with least-privilege IAM, structured logging, sensible timeout and memory settings, and pay-per-request defaults, following AWS Well-Architected serverless best practices. license: Apache-2.0 metadata: source: agent-toolkit-for-aws --- # Serverless API (Lambda + API Gateway) Ship an HTTP API backed by AWS Lambda behind Amazon API Gateway, defined as infrastructure-as-code. Follow the `working-with-aws` guardrails throughout. ## Decide the shape first - **HTTP API** (API Gateway v2) — lower cost and latency; the default for most JSON APIs. - **REST API** (API Gateway v1) — choose only if you need request/response transformations, API keys/usage plans, WAF at the stage, or edge-optimized endpoints. - **Function URL** — a single function with no routing needs; skip API Gateway. ## Well-Architected defaults - **Least-privilege role.** Give the function only the actions it uses. Start from an empty policy and add statements per integration. - **Memory and timeout.** Start at 256–512 MB and a timeout just above your p99 (e.g. 10s for a web request path); tune from real metrics, not guesses. - **Structured JSON logs** to CloudWatch; emit a request id on every line. - **Pay-per-request.** Prefer on-demand concurrency; add provisioned concurrency only if cold starts violate a latency SLO. - **Idempotency** for any write path that a client may retry. ## Option A — AWS SAM (fastest path) `template.yaml`: ```yaml AWSTemplateFormatVersion: "2010-09-09" Transform: AWS::Serverless-2016-10-31 Globals: Function: Runtime: python3.12 MemorySize: 256 Timeout: 10 LoggingConfig: LogFormat: JSON Resources: ApiFunction: Type: AWS::Serverless::Function Properties: Handler: app.handler CodeUri: src/ Events: Api: Type: HttpApi Properties: Path: /items Method: GET Outputs: ApiUrl: Value: !Sub "https://${ServerlessHttpApi}.execute-api.${AWS::Region}.amazonaws.com" ``` Deploy: `sam build && sam deploy --guided`. SAM creates the HTTP API, the function, and a scoped execution role automatically. ## Option B — AWS CDK (TypeScript) ```ts import { Stack, StackProps, Duration } from "aws-cdk-lib"; import { Construct } from "constructs"; import { HttpApi, HttpMethod } from "aws-cdk-lib/aws-apigatewayv2"; import { HttpLambdaIntegration } from "aws-cdk-lib/aws-apigatewayv2-integrations"; import { Runtime, LoggingFormat } from "aws-cdk-lib/aws-lambda"; import { NodejsFunction } from "aws-cdk-lib/aws-lambda-nodejs"; export class ServerlessApiStack extends Stack { constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props); const fn = new NodejsFunction(this, "ApiFunction", { runtime: Runtime.NODEJS_20_X, memorySize: 256, timeout: Duration.seconds(10), loggingFormat: LoggingFormat.JSON, entry: "src/app.ts", }); const api = new HttpApi(this, "HttpApi"); api.addRoutes({ path: "/items", methods: [HttpMethod.GET], integration: new HttpLambdaIntegration("ItemsIntegration", fn), }); } } ``` Deploy: `cdk deploy`. CDK synthesizes least-privilege permissions for the integrations you declare. ## Verify 1. Call the output URL: `curl https://.execute-api..amazonaws.com/items`. 2. Confirm structured logs and no permission errors in CloudWatch Logs. 3. Check the function's IAM role has only the statements it needs. If you need help wiring a data store behind the function, load the `choose-a-database` skill.