Introduction
Amazon API Gateway is a fully managed AWS service for creating, deploying, and managing REST, HTTP, or WebSocket APIs at scale. In 2026, it natively supports features like IAM authentication, Cognito, Lambda Authorizers, and advanced throttling for serverless workloads.
Why use it? Unlike traditional EC2 servers, API Gateway handles scalability, security (WAF, DDoS protection via Shield), CloudWatch metrics, and direct integrations with Lambda or other AWS services automatically. This intermediate tutorial walks you through deploying a complete REST API with AWS SAM (Serverless Application Model), including a Lambda function, CRUD routes, basic authorization, and end-to-end tests.
By the end, you'll have a live, monitorable API with an optional custom domain. Ideal for microservices or mobile backends. Estimated time: 30 minutes. (128 words)
Prerequisites
- Active AWS account with IAM permissions for API Gateway, Lambda, CloudFormation, and S3 (AdministratorAccess policy for testing).
- AWS CLI v2 installed and configured (
aws configure). - AWS SAM CLI installed (see next step).
- Node.js 18+ or Python 3.9+ for Lambda handlers.
- Tools:
curlfor testing, code editor (VS Code recommended).
Install AWS SAM CLI
# macOS avec Homebrew
brew tap aws/tap
brew install aws-sam-cli
# Linux (Amazon Linux 2023 ou Ubuntu)
curl -L https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip -o aws-sam-cli.zip
unzip aws-sam-cli.zip -d sam-installation
sudo ./sam-installation/install
# Vérifier l'installation
sam --versionThese commands install SAM CLI, the command-line tool for developing and deploying AWS serverless apps. It handles CloudFormation synthesis and local/emulated deployments. Avoid outdated versions; always use the latest release for 2026 compatibility with new features like Provisioned Concurrency.
Initialize the SAM Project
Create a basic SAM app with an API Gateway + Lambda template. This generates a standard structure: template.yaml, Lambda handler, and samconfig.toml for deployments.
Initialize the SAM App
sam init --runtime nodejs18.x --name mon-api-gateway --app-template aws-nodejs-apigateway-lambda --location ./mon-api-gateway
cd mon-api-gateway
sam buildInitialization creates a complete skeleton with REST API Gateway and a Node.js Lambda. sam build compiles the project into deployment-ready artifacts. Tip: Use the right runtime; nodejs18.x is optimal in 2026 for V8 performance and shared layers.
Define the API Gateway Template
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: API REST avec Gateway + Lambda
Globals:
Function:
Timeout: 30
Runtime: nodejs18.x
MemorySize: 512
Environment:
Variables:
TABLE_NAME: !Ref MyDynamoTable
Resources:
MyApi:
Type: AWS::Serverless::Api
Properties:
StageName: Prod
Cors:
AllowMethods: "*"
AllowHeaders: "*"
AllowOrigin: "*"
Auth:
DefaultAuthorizer: MyAuthorizer
AddDefaultAuthorizerToCorsPreflight: false
GetHandler:
Type: AWS::Serverless::Function
Properties:
CodeUri: hello-world/
Handler: app.lambdaHandler
Events:
GetResource:
Type: Api
Properties:
RestApiId: !Ref MyApi
Path: /{proxy+}
Method: GET
PostHandler:
Type: AWS::Serverless::Function
Properties:
CodeUri: hello-world/
Handler: app.createHandler
Events:
PostResource:
Type: Api
Properties:
RestApiId: !Ref MyApi
Path: /{proxy+}
Method: POST
MyAuthorizer:
Type: AWS::Serverless::SimpleTable
Properties:
PrimaryKey:
Name: id
Type: String
Outputs:
ApiGatewayUrl:
Description: URL de l'API
Value: !Sub https://${MyApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/This template defines a REST API with proxy routes /{proxy+} mapped to GET/POST Lambdas. It includes global CORS, a basic authorizer, and a DynamoDB table. Benefit: SAM automates integrations; tip: 30s timeout max to avoid excessive cold starts.
Implement the Lambda Handler
const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB.DocumentClient();
const TABLE_NAME = process.env.TABLE_NAME;
exports.lambdaHandler = async (event) => {
try {
const params = {
TableName: TABLE_NAME,
Key: { id: event.pathParameters.proxy }
};
const result = await dynamodb.get(params).promise();
const response = {
statusCode: 200,
headers: { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' },
body: JSON.stringify(result.Item || { message: 'Item non trouvé' })
};
return response;
} catch (err) {
return {
statusCode: 500,
body: JSON.stringify({ error: err.message })
};
}
};
exports.createHandler = async (event) => {
try {
const data = JSON.parse(event.body);
const params = {
TableName: TABLE_NAME,
Item: { id: data.id, name: data.name }
};
await dynamodb.put(params).promise();
return {
statusCode: 201,
headers: { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' },
body: JSON.stringify({ message: 'Item créé' })
};
} catch (err) {
return {
statusCode: 500,
body: JSON.stringify({ error: err.message })
};
}
};This handler manages GET (fetch from DynamoDB) and POST (create item). It uses pathParameters for /{proxy+} and handles errors with try/catch. Why DocumentClient? Simpler than low-level SDK; tip: Always parse event.body and add CORS headers manually for API Gateway.
Deploy the API
Note: Replace us-east-1 with your region. SAM validates and deploys via CloudFormation. The API goes live immediately after.
Deploy with SAM
# Build et deploy
sam build --use-container
sam deploy --guided --stack-name mon-api-stack --region us-east-1 --capabilities CAPABILITY_IAM --resolve-s3
# Récupérer l'URL (dans les outputs CloudFormation)
aws cloudformation describe-stacks --stack-name mon-api-stack --query 'Stacks[0].Outputs[?OutputKey==`ApiGatewayUrl`].OutputValue' --output text--use-container ensures Docker-based reproducibility. --guided auto-configures S3 bucket. --capabilities CAPABILITY_IAM for Lambda roles. Tip: Check outputs for the URL; without --resolve-s3, assets won't resolve.
Test the API
API_URL=$(aws cloudformation describe-stacks --stack-name mon-api-stack --query 'Stacks[0].Outputs[?OutputKey==`ApiGatewayUrl`].OutputValue' --output text)
# POST créer item
curl -X POST $API_URL/test1 -H "Content-Type: application/json" -d '{"id":"test1","name":"Mon Item"}'
# GET récupérer
curl $API_URL/test1These curl commands test CRUD via proxy path. Replace API_URL with your actual output. Success: 200/201 with JSON. Tip: Without -H Content-Type, JSON parsing fails; check CloudWatch Logs for Lambda debugging.
Clean Up Resources
sam delete --stack-name mon-api-stack --region us-east-1
aws cloudformation delete-stack --stack-name mon-api-stack --region us-east-1Deletes the CloudFormation stack and associated resources (API, Lambda, DynamoDB). Essential to avoid costs. SAM delete is safer as it handles dependencies; use --no-prompt in CI/CD.
Best Practices
- Use advanced Authorizers: Integrate Cognito or Lambda Authorizer for JWT/OAuth in production, not just IAM.
- Enable WAF and throttling: Add AWS::WAFv2::WebACL to your template for DDoS and rate limiting.
- Logging and monitoring: Enable Access Logs on API Gateway to CloudWatch Logs; use X-Ray for tracing.
- Custom Domain + ACM: Associate a domain via Route 53 and free ACM certificate.
- CI/CD with SAM Pipelines: Automate builds/deploys with GitHub Actions or CodePipeline.
Common Errors to Avoid
- Excessive cold starts: Provision concurrency on Lambda or use SnapStart (for Java/Rust).
- Misconfigured CORS: Always set
Corsin SAM and headers in handler; test OPTIONS preflight. - Missing permissions: Lambda needs
dynamodb:*on the table; SAM auto-generates but verify in multi-region. - Overly permissive proxy path: Use specific routes instead of /{proxy+} for security.
Next Steps
- Official documentation: AWS API Gateway.
- Advanced WebSocket tutorial: here.
- Complete training: Check out our AWS Learni training for Solutions Architect certification.
- Tools: AWS CDK for TypeScript IaC, or Serverless Framework as a SAM alternative.