Busque em todas as páginas da documentação
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥
npm install @aws-sdk/client-lambda// lib/lambda.ts
import { LambdaClient } from "@aws-sdk/client-lambda";
export const lambdaClient = new LambdaClient({
region: process.env.AWS_REGION!,
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
},
});// lib/invoke-lambda.ts
import { InvokeCommand } from "@aws-sdk/client-lambda";
import { lambdaClient } from "./lambda";
export async function invokeLambda<TInput, TOutput>(
functionName: string,
payload: TInput
): Promise<TOutput> {
const command = new InvokeCommand({
FunctionName: functionName,
Payload: new TextEncoder().encode(JSON.stringify(payload)),
});
const response = await lambdaClient.send(command);
if (response.FunctionError) {
const errorPayload = JSON.parse(
new TextDecoder().decode(response.Payload)
);
throw new Error(
`Lambda error: ${errorPayload.errorMessage ?? response.FunctionError}`
);
}
return JSON.parse(new TextDecoder().decode(response.Payload)) as TOutput;
}Quando usar isso: Você precisa invocar funções AWS Lambda de uma aplicação Next.js para processamento em segundo plano, computação pesada ou acesso a serviços nativos da AWS.
// app/components/ImageProcessor.tsx
"use client";
import { useState } from "react";
import { processImage } from "../actions/image-actions";
export default function ImageProcessor() {
const [result, setResult] = useState<{
thumbnailUrl: string;
dimensions: { width: number; height: number };
} | null>(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
async function handleProcess(formData: FormData) {
setLoading(true);
setError(null);
try {
const data = await processImage(formData);
setResult(data);
} catch (err) {
setError(err instanceof Error ? err.message : "Processing failed");
} finally {
setLoading(false);
}
}
return (
<div className="max-w-md mx-auto p-6 space-y-4">
<form action={handleProcess}>
<input name="imageUrl" placeholder="Image URL" required className="w-full border rounded px-3 py-2" />
<input name="width" type="number" placeholder="Target width" defaultValue={200} className="w-full border rounded px-3 py-2 mt-2" />
<button
type="submit"
disabled={loading}
className="mt-3 bg-blue-600 text-white px-4 py-2 rounded disabled:opacity-50"
>
{loading ? "Processing..." : "Process Image"}
</button>
</form>
{error && <p className="text-red-600">{error}</p>}
{result && (
<div>
<p>Thumbnail: {result.dimensions.width}x{result.dimensions.height}</p>
<img src={result.thumbnailUrl} alt="Processed thumbnail" className="border rounded" />
</div>
)}
</div>
);
}// app/actions/image-actions.ts
"use server";
import { invokeLambda } from "@/lib/invoke-lambda";
interface ProcessImageInput {
imageUrl: string;
targetWidth: number;
}
interface ProcessImageOutput {
thumbnailUrl: string;
dimensions: { width: number; height: number };
}
export async function processImage(formData: FormData) {
const imageUrl = formData.get("imageUrl") as string;
const targetWidth = Number(formData.get("width")) || 200;
const result = await invokeLambda<ProcessImageInput, ProcessImageOutput>(
"image-processor",
{ imageUrl, targetWidth }
);
return result;
}O que isso demonstra:
InvokeCommand envia o payload como um Uint8Array e recebe a resposta da mesma formaFunctionError na resposta indica se a função Lambda lançou um erroInvocação Assíncrona (disparar e esquecer):
import { InvokeCommand, InvocationType } from "@aws-sdk/client-lambda";
const command = new InvokeCommand({
FunctionName: "email-sender",
InvocationType: InvocationType.Event, // async, retorna 202 imediatamente
Payload: new TextEncoder().encode(
JSON.stringify({ to: "user@example.com", subject: "Welcome!" })
),
});
await lambdaClient.send(command); // Retorna imediatamente, sem payload de respostaDry run (validar permissões e entrada):
const command = new InvokeCommand({
FunctionName: "my-function",
InvocationType: InvocationType.DryRun,
Payload: new TextEncoder().encode(JSON.stringify({ test: true })),
});
// Retorna 204 se válido, lança erro se as permissões estiverem incorretas
await lambdaClient.send(command);Listar funções disponíveis:
import { ListFunctionsCommand } from "@aws-sdk/client-lambda";
const command = new ListFunctionsCommand({ MaxItems: 50 });
const response = await lambdaClient.send(command);
const functions = response.Functions?.map((fn) => ({
name: fn.FunctionName,
runtime: fn.Runtime,
memory: fn.MemorySize,
lastModified: fn.LastModified,
}));Invocar com qualificador (versão ou alias):
const command = new InvokeCommand({
FunctionName: "my-function",
Qualifier: "production", // nome do alias ou número da versão
Payload: new TextEncoder().encode(JSON.stringify(payload)),
});InvokeCommandOutput.Payload é Uint8Array | undefined - sempre verifique se não é undefined antes de decodificarInvocationType fornece RequestResponse (síncrono), Event (assíncrono) e DryRunimport type { InvokeCommandOutput } from "@aws-sdk/client-lambda";
function decodePayload<T>(response: InvokeCommandOutput): T | null {
if (!response.Payload) return null;
return JSON.parse(new TextDecoder().decode(response.Payload)) as T;
}Codificação do payload - Passar uma string simples ou objeto como Payload lança um erro de tipo. Correção: Sempre codifique com new TextEncoder().encode(JSON.stringify(data)) e decodifique respostas com new TextDecoder().decode(response.Payload).
Latência de cold start - As primeiras invocações após períodos de inatividade levam vários segundos. Correção: Use provisioned concurrency para funções sensíveis à latência, ou aceite cold starts e mostre estados de carregamento na UI.
Discrepância de timeout - Funções Lambda têm um timeout padrão de 3 segundos, mas o processamento pode levar mais tempo. Correção: Defina o timeout da função Lambda apropriadamente na AWS. Considere também a invocação assíncrona para tarefas de longa duração.
Falhas silenciosas com invocação assíncrona - InvocationType: "Event" retorna 202 sem detalhes de erro. Correção: Configure uma Dead Letter Queue (DLQ) na função Lambda para capturar invocações assíncronas falhas.
Limite de tamanho do payload - Payloads síncronos são limitados a 6MB. Correção: Para dados maiores, armazene-os no S3 e passe a chave do S3 no payload.
Permissões ausentes - O usuário ou role IAM precisa da permissão lambda:InvokeFunction. Correção: Adicione a permissão à sua política IAM para o ARN específico da função.
| Biblioteca | Ideal Para | Contrapartida |
|---|---|---|
| @aws-sdk/client-lambda | Invocação direta de Lambda | Requer configuração AWS, permissões IAM |
| Next.js API Routes | Lógica do lado do servidor na mesma aplicação | Tempo de execução limitado, recursos compartilhados |
| Vercel Functions | Serverless na Vercel | Específico da Vercel, menos controle |
| AWS API Gateway + Lambda | Pontos de extremidade de API públicos | Mais infraestrutura para gerenciar |
| Step Functions | Orquestração de múltiplas Lambdas | Maior complexidade, custo adicional |
InvokeCommand espera Payload como um Uint8Array, não um objeto ou string simplesnew TextEncoder().encode(JSON.stringify(data)) para converterUint8Array e precisam de new TextDecoder().decode()InvocationType: "Event"): Retorna HTTP 202 imediatamente, sem payload de respostaconst response = await lambdaClient.send(command);
if (response.FunctionError) {
const error = JSON.parse(
new TextDecoder().decode(response.Payload)
);
throw new Error(error.errorMessage);
}O campo FunctionError é definido quando a Lambda lança um erro; o payload contém detalhes do erro.
InvocationType: "Event" retorna 202 sem detalhes de erro, mesmo que a função falheasync function invokeLambda<TInput, TOutput>(
functionName: string,
payload: TInput
): Promise<TOutput> {
const command = new InvokeCommand({
FunctionName: functionName,
Payload: new TextEncoder().encode(JSON.stringify(payload)),
});
const response = await lambdaClient.send(command);
return JSON.parse(
new TextDecoder().decode(response.Payload)
) as TOutput;
}Payload é tipado como Uint8Array | undefinedundefined antes de decodificaras T para o seu tipo de retorno esperadoconst command = new InvokeCommand({
FunctionName: "my-function",
Qualifier: "production", // alias ou número da versão
Payload: new TextEncoder().encode(JSON.stringify(payload)),
});lambda:InvokeFunctionlambda:ListFunctions se você também precisar listar funções disponíveis"use server";
import { invokeLambda } from "@/lib/invoke-lambda";
export async function processImage(formData: FormData) {
const imageUrl = formData.get("imageUrl") as string;
return invokeLambda("image-processor", { imageUrl });
}Server Actions mantêm as credenciais da AWS no servidor e fornecem uma API limpa para componentes do cliente.
InvocationType: "DryRun" valida permissões e entrada sem executar a funçãoRevisado por Chris St. John·Última atualização: 10 de jul. de 2026
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥