Use Cases

Claude Code × AWS API Gateway Guia Completo | Design de REST API até Automação de Deploy

Automatize o design de endpoints do AWS API Gateway com Claude Code. Design de recursos, integração Lambda, autenticação e deploy — com código real da experiência profissional de Masa.

Como o Tempo de Design do API Gateway Caiu para um Terço

Sou Masa, administro o claudecode-lab.com. Quando trabalhava como desenvolvedor backend freelance, o design e a implementação do AWS API Gateway liderava a lista de “tarefas tediosas e demoradas”. Escrever documentos de especificação de endpoints, traduzi-los para CloudFormation, conectar integrações Lambda manualmente, configurar CORS — e cometer os mesmos erros repetidamente.

A virada chegou há cerca de seis meses, quando pedi ao Claude Code: “Projete uma REST API baseada neste caso de uso e implemente-a em CDK.” O resultado foi surpreendentemente pronto para produção, e desde então o tempo de implementação do API Gateway caiu para um terço.


Passo 1: Delegando o Design de Endpoints REST API ao Claude Code

Exemplo de Prompt

Crie uma especificação de endpoints REST API com base nos seguintes casos de uso.

Casos de uso:
- App de gerenciamento de tarefas (usuários gerenciam projetos e tarefas)
- Autenticação de usuário necessária (Cognito)
- Projetos podem ter membros
- Tarefas suportam comentários e anexos

Formato de saída:
- Lista de endpoints (método, caminho, descrição)
- Schemas JSON de request/response
- Marcar endpoints que requerem autenticação
- Indicar violações de princípios REST

Passo 2: Auto-Geração da Configuração de Integração Lambda

CDK Stack Gerado (trecho)

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 funções 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 máximo do 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");

    // ===== Definição da REST API =====
    this.api = new apigateway.RestApi(this, "TaskApi", {
      restApiName: "task-management-api",
      defaultCorsPreflightOptions: {
        allowOrigins: apigateway.Cors.ALL_ORIGINS, // restringir em produção
        allowMethods: apigateway.Cors.ALL_METHODS,
        allowHeaders: ["Content-Type", "Authorization", "X-Api-Key"],
      },
      deployOptions: {
        stageName: "v1",
        loggingLevel: apigateway.MethodLoggingLevel.INFO,
        dataTraceEnabled: false,
      },
    });

    // ===== Recursos e métodos =====
    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 do API Gateway",
    });
  }
}

Passo 3: Autenticação (Cognito / Lambda Authorizer / API Key)

Padrão 1: Cognito User Pool Authorizer

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,
});

Padrão 2: Lambda Authorizer

// src/handlers/auth/authorizer.ts
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");
  }
};

Passo 4: Gerenciamento de Stages (dev/staging/prod)

# Deploy para desenvolvimento
CDK_ENV=dev npx cdk deploy Api-dev --require-approval never

# Staging
CDK_ENV=staging npx cdk deploy Api-staging

# Produção (com confirmação)
CDK_ENV=prod npx cdk deploy Api-prod

4 Armadilhas Comuns

Armadilha 1: Configuração CORS Ausente (a mais frequente)

// ❌ Insuficiente
defaultCorsPreflightOptions: { allowOrigins: apigateway.Cors.ALL_ORIGINS }

// ✅ Sempre adicionar headers CORS nas respostas 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),
};

Armadilha 2: Permissão de Invocação Lambda Ausente

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

Armadilha 3: O Limite de Timeout de 29 Segundos

// ✅ Padrão assíncrono: retornar job ID imediatamente
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" }),
  };
};

Armadilha 4: Body da Requisição Ausente no Lambda

// ✅ Sempre definir proxy: true explicitamente
project.addMethod("POST", new apigateway.LambdaIntegration(createProjectFn, { proxy: true }));

Resumo

TarefaValor do Claude CodeDificuldade
Design REST APIAuto-gerar specs, verificar princípios RESTBaixa
Lambda Integration CDKGerar proxy integration + definições de recursosBaixa
Auth CognitoGerar User Pool, Authorizer, config de clienteMédia
Lambda AuthorizerImplementar validação JWT + geração de policyMédia
Gerenciamento de stagesSeparar configs de env, gerar comandos de deployMédia
Processamento assíncronoProjetar integração SQS + padrão de pollingAlta

Resultado prático: tempo de design API Gateway até deploy CDK reduzido de 3 dias para 1 dia. A configuração do Cognito Authorizer, que antes requeria mais de uma hora lendo documentação AWS, agora se resolve com um único prompt do Claude Code.


Artigos Relacionados

Referências

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

Leve seu fluxo no Claude Code a outro nível

50 modelos de prompt testados em campo, prontos para colar direto no Claude Code.

Grátis

PDF gratuito: Cheatsheet do Claude Code em 5 minutos

Basta informar seu e-mail e enviamos na hora o cheatsheet em uma página A4.

Cuidamos dos seus dados pessoais e nunca enviamos spam.

Masa

Sobre o autor

Masa

Engenheiro apaixonado por Claude Code. Mantém o claudecode-lab.com, uma mídia tech em 10 idiomas com mais de 2.000 páginas.