Use Cases

Claude Code × AWS API Gateway Guide Complet | Conception REST API jusqu'à l'automatisation du déploiement

Automatisez la conception des endpoints AWS API Gateway avec Claude Code. Conception des ressources, intégration Lambda, authentification et déploiement — avec du code réel tiré de l'expérience professionnelle de Masa.

Comment le temps de conception API Gateway a été réduit au tiers

Je suis Masa, je gère claudecode-lab.com. Quand je travaillais comme développeur backend freelance, la conception et l’implémentation d’AWS API Gateway trônait en tête de liste des “tâches fastidieuses et chronophages”. Rédiger des documents de spécification d’endpoints, les traduire en CloudFormation, câbler manuellement les intégrations Lambda, configurer les CORS — et répéter les mêmes erreurs à chaque fois.

Le tournant est arrivé il y a environ six mois, quand j’ai demandé à Claude Code : “Conçois une REST API basée sur ce cas d’usage et implémente-la en CDK.” Le résultat était étonnamment prêt pour la production, et depuis lors, le temps d’implémentation API Gateway a été réduit au tiers.

Oublis CORS, erreurs de permissions Lambda, le piège du timeout de 29 secondes — depuis que Claude Code détecte ces problèmes en amont, les findings de revue ont également chuté drastiquement.


Pourquoi Claude Code excelle dans la conception API Gateway

La conception API Gateway a une caractéristique distinctive : elle ne nécessite pas de connaissances profondes, mais implique beaucoup de boilerplate répétitif.

  • Conventions de nommage des endpoints (substantifs au pluriel, structure hiérarchique)
  • Sélection des méthodes HTTP (GET/POST/PUT/PATCH/DELETE)
  • Définitions des schémas request/response
  • Mapping des variables de chemin pour l’intégration Lambda
  • Configuration des en-têtes CORS (toujours quelque chose d’oublié)
  • Gestion des variables de stage (dev/staging/prod)

Étape 1 : Déléguer la conception des endpoints REST API à Claude Code

Exemple de Prompt

Crée une spécification d'endpoints REST API basée sur les cas d'usage suivants.

Cas d'usage :
- App de gestion de tâches (les utilisateurs gèrent des projets et des tâches)
- Authentification utilisateur requise (Cognito)
- Les projets peuvent avoir des membres
- Les tâches supportent les commentaires et les pièces jointes

Format de sortie :
- Liste des endpoints (méthode, chemin, description)
- Schémas JSON request/response
- Marquer les endpoints nécessitant une authentification
- Signaler les violations des principes REST

Étape 2 : Auto-génération de la configuration d’intégration Lambda

Stack CDK généré (extrait)

import * as cdk from "aws-cdk-lib";
import * as apigateway from "aws-cdk-lib/aws-apigateway";
import * as nodejs from "aws-cdk-lib/aws-lambda-nodejs";
import * as lambda from "aws-cdk-lib/aws-lambda";
import { Construct } from "constructs";

export class TaskApiStack extends cdk.Stack {
  public readonly api: apigateway.RestApi;

  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // ===== Factory de fonctions Lambda =====
    const createLambda = (name: string, handler: string) =>
      new nodejs.NodejsFunction(this, name, {
        entry: `src/handlers/${handler}.ts`,
        handler: "handler",
        runtime: lambda.Runtime.NODEJS_20_X,
        timeout: cdk.Duration.seconds(29), // Timeout max d'API Gateway
        memorySize: 256,
        bundling: {
          minify: true,
          sourceMap: true,
          externalModules: ["@aws-sdk/*"],
        },
      });

    const listProjectsFn = createLambda("ListProjects", "projects/list");
    const createProjectFn = createLambda("CreateProject", "projects/create");
    const getProjectFn = createLambda("GetProject", "projects/get");
    const updateProjectFn = createLambda("UpdateProject", "projects/update");
    const deleteProjectFn = createLambda("DeleteProject", "projects/delete");

    // ===== Définition de la REST API =====
    this.api = new apigateway.RestApi(this, "TaskApi", {
      restApiName: "task-management-api",
      defaultCorsPreflightOptions: {
        allowOrigins: apigateway.Cors.ALL_ORIGINS, // à restreindre en production
        allowMethods: apigateway.Cors.ALL_METHODS,
        allowHeaders: ["Content-Type", "Authorization", "X-Api-Key"],
      },
      deployOptions: {
        stageName: "v1",
        loggingLevel: apigateway.MethodLoggingLevel.INFO,
        dataTraceEnabled: false,
      },
    });

    // ===== Ressources et méthodes =====
    const projects = this.api.root.addResource("projects");
    projects.addMethod("GET", new apigateway.LambdaIntegration(listProjectsFn));
    projects.addMethod("POST", new apigateway.LambdaIntegration(createProjectFn));

    const project = projects.addResource("{id}");
    project.addMethod("GET", new apigateway.LambdaIntegration(getProjectFn));
    project.addMethod("PUT", new apigateway.LambdaIntegration(updateProjectFn));
    project.addMethod("DELETE", new apigateway.LambdaIntegration(deleteProjectFn));

    new cdk.CfnOutput(this, "ApiUrl", {
      value: this.api.url,
      description: "URL API Gateway",
    });
  }
}

Étape 3 : Authentification (Cognito / Lambda Authorizer / Clé API)

Modèle 1 : Cognito User Pool Authorizer (BtoC)

import * as cognito from "aws-cdk-lib/aws-cognito";

const userPool = new cognito.UserPool(this, "UserPool", {
  userPoolName: "task-app-users",
  selfSignUpEnabled: true,
  signInAliases: { email: true },
  passwordPolicy: {
    minLength: 8,
    requireLowercase: true,
    requireUppercase: true,
    requireDigits: true,
  },
});

const cognitoAuthorizer = new apigateway.CognitoUserPoolsAuthorizer(
  this,
  "CognitoAuthorizer",
  {
    cognitoUserPools: [userPool],
    identitySource: "method.request.header.Authorization",
    resultsCacheTtl: cdk.Duration.minutes(5),
  }
);

projects.addMethod("GET", new apigateway.LambdaIntegration(listProjectsFn), {
  authorizer: cognitoAuthorizer,
  authorizationType: apigateway.AuthorizationType.COGNITO,
});

Modèle 2 : Lambda Authorizer

// src/handlers/auth/authorizer.ts
import {
  APIGatewayAuthorizerResult,
  APIGatewayTokenAuthorizerHandler,
} from "aws-lambda";
import * as jwt from "jsonwebtoken";

export const handler: APIGatewayTokenAuthorizerHandler = async (event) => {
  const token = event.authorizationToken.replace("Bearer ", "");

  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET!) as {
      sub: string;
      email: string;
      role: string;
    };

    return generatePolicy(decoded.sub, "Allow", event.methodArn, {
      userId: decoded.sub,
      email: decoded.email,
      role: decoded.role,
    });
  } catch {
    throw new Error("Unauthorized");
  }
};

function generatePolicy(
  principalId: string,
  effect: "Allow" | "Deny",
  resource: string,
  context?: Record<string, string>
): APIGatewayAuthorizerResult {
  return {
    principalId,
    policyDocument: {
      Version: "2012-10-17",
      Statement: [
        {
          Action: "execute-api:Invoke",
          Effect: effect,
          Resource: resource.replace(/\/[^/]+\/[^/]+$/, "/*/*"),
        },
      ],
    },
    context,
  };
}

Étape 4 : Gestion des Stages (dev/staging/prod)

// lib/config.ts
export type Stage = "dev" | "staging" | "prod";

export const stageConfig: Record<Stage, {
  throttleRateLimit: number;
  corsOrigins: string[];
  enableDataTrace: boolean;
}> = {
  dev: {
    throttleRateLimit: 10,
    corsOrigins: ["http://localhost:3000"],
    enableDataTrace: true,
  },
  staging: {
    throttleRateLimit: 50,
    corsOrigins: ["https://staging.example.com"],
    enableDataTrace: false,
  },
  prod: {
    throttleRateLimit: 1000,
    corsOrigins: ["https://example.com"],
    enableDataTrace: false,
  },
};
# Déploiement en développement
CDK_ENV=dev npx cdk deploy Api-dev --require-approval never

# Staging
CDK_ENV=staging npx cdk deploy Api-staging

# Production (avec confirmation)
CDK_ENV=prod npx cdk deploy Api-prod

4 Pièges Courants

Piège 1 : Configuration CORS manquante (le plus fréquent)

// ❌ Insuffisant
defaultCorsPreflightOptions: {
  allowOrigins: apigateway.Cors.ALL_ORIGINS,
}

// ✅ Toujours ajouter les en-têtes CORS dans les réponses Lambda
return {
  statusCode: 200,
  headers: {
    "Content-Type": "application/json",
    "Access-Control-Allow-Origin": "https://example.com",
    "Access-Control-Allow-Credentials": "true",
  },
  body: JSON.stringify(data),
};

Piège 2 : Permission d’invocation Lambda manquante

listProjectsFn.addPermission("ApiGatewayInvoke", {
  principal: new iam.ServicePrincipal("apigateway.amazonaws.com"),
  sourceArn: this.api.arnForExecuteApi("GET", "/projects", "v1"),
});

Piège 3 : La limite de timeout de 29 secondes

// ✅ Modèle asynchrone : retourner un job ID immédiatement
export const startExport: APIGatewayProxyHandler = async (event) => {
  const jobId = crypto.randomUUID();

  await sqsClient.send(
    new SendMessageCommand({
      QueueUrl: process.env.JOB_QUEUE_URL!,
      MessageBody: JSON.stringify({ jobId, params: JSON.parse(event.body!) }),
    })
  );

  return {
    statusCode: 202,
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ jobId, status: "processing" }),
  };
};

Piège 4 : Corps de requête manquant dans Lambda

// ✅ Toujours définir proxy: true explicitement
project.addMethod(
  "POST",
  new apigateway.LambdaIntegration(createProjectFn, {
    proxy: true,
  })
);

Résumé

TâcheValeur de Claude CodeDifficulté
Conception REST APIAuto-générer les specs, vérifier les principes RESTFaible
Lambda Integration CDKGénérer l’intégration proxy + définitions de ressourcesFaible
Auth CognitoGénérer User Pool, Authorizer, config clientMoyenne
Lambda AuthorizerImplémenter validation JWT + génération de policyMoyenne
Gestion des stagesSéparer les configs d’env, générer les commandes de déploiementMoyenne
Traitement asynchroneConcevoir l’intégration SQS + modèle de pollingÉlevée

Résultat pratique : temps de conception API Gateway-to-CDK-deploy réduit de 3 jours à 1 jour. La configuration Cognito Authorizer, qui nécessitait auparavant plus d’une heure de lecture de documentation AWS, se résout maintenant avec un seul prompt Claude Code.


Articles Connexes

Références

#claude-code #aws #api-gateway #lambda #typescript #rest-api

Passez votre flux Claude Code au niveau supérieur

50 modèles de prompts éprouvés, prêts à être copiés-collés dans Claude Code.

Gratuit

PDF gratuit : aide-mémoire Claude Code en 5 minutes

Laissez simplement votre e-mail et nous vous enverrons immédiatement l'aide-mémoire A4 en PDF.

Nous traitons vos données avec soin et n'envoyons jamais de spam.

Masa

À propos de l'auteur

Masa

Ingénieur passionné par Claude Code. Il gère claudecode-lab.com, un média tech en 10 langues avec plus de 2 000 pages.