Skip to content
Learni
View all tutorials
AWS

How to Deploy a REST API with Amazon API Gateway in 2026

Lire en français

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: curl for testing, code editor (VS Code recommended).

Install AWS SAM CLI

terminal
# 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 --version

These 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

terminal
sam init --runtime nodejs18.x --name mon-api-gateway --app-template aws-nodejs-apigateway-lambda --location ./mon-api-gateway
cd mon-api-gateway
sam build

Initialization 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

template.yaml
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

hello-world/app.js
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

terminal
# 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

terminal
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/test1

These 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

terminal
sam delete --stack-name mon-api-stack --region us-east-1
aws cloudformation delete-stack --stack-name mon-api-stack --region us-east-1

Deletes 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 Cors in 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.