Pular para o conteúdo

tRPC

Filter this guidePick generator option values to hide sections that don't apply.

tRPC é um framework para construir APIs em TypeScript com segurança de tipos end-to-end. Usando tRPC, atualizações nas entradas e saídas das operações da API são imediatamente refletidas no código do cliente e visíveis na sua IDE sem necessidade de reconstruir o projeto.

O gerador de API tRPC cria uma nova API tRPC com configuração de infraestrutura AWS CDK ou Terraform. O backend gerado utiliza AWS Lambda para implantação serverless, exposto via AWS API Gateway API, e inclui validação de schema usando Zod. Configura AWS Lambda Powertools para observabilidade, incluindo logging, rastreamento com AWS X-Ray e métricas no Cloudwatch.

Você pode gerar uma nova API tRPC de duas formas:

  1. Instale o Nx Console VSCode Plugin se ainda não o fez
  2. Abra o console Nx no VSCode
  3. Clique em Generate (UI) na seção "Common Nx Commands"
  4. Procure por @aws/nx-plugin - ts#api
  5. Preencha os parâmetros obrigatórios
    • framework: trpc
  6. Clique em Generate
ParâmetroTipoPadrãoDescrição
name Obrigatóriostring-O nome da API (obrigatório). Usado para gerar nomes de classes e caminhos de arquivos.
framework trpc | smithytrpcO framework de API a ser utilizado.
namespace string-O namespace para a API Smithy (aplicável apenas para o framework smithy). O padrão é o escopo do seu monorepo
integrationPattern isolated | sharedisolatedComo as integrações do API Gateway são geradas para a API. Escolha entre isolated (padrão) e shared.
auth iam | cognito | customiamO método usado para autenticar com sua API. Escolha entre iam (padrão), cognito ou custom.
directory stringpackagesO diretório para armazenar a aplicação.
subDirectory string-O subdiretório onde o projeto é colocado. Por padrão, este é o nome do projeto.
iac inherit | cdk | terraforminheritO provedor IaC preferido. Por padrão, isso é herdado da sua seleção inicial.
infra rest-lambda | http-lambda | nonerest-lambdaO tipo de infraestrutura a ser usado para implantar esta API.
preferInstallDependencies booleantrueSe deve preferir instalar dependências após a execução do gerador. Defina como false para adiar a instalação ao executar múltiplos geradores em lote (uma instalação ainda é executada se necessário para que geradores subsequentes possam calcular o grafo de projetos Nx); instale uma vez no final.

O gerador criará a seguinte estrutura de projeto no diretório <directory>/<api-name>:

  • Directorysrc
    • init.ts Inicialização do backend tRPC
    • handler.ts Ponto de entrada do handler Lambda
    • router.ts Definição do roteador tRPC
    • Directoryschema Definições de schema usando Zod
      • echo.ts Exemplo de definições para entrada e saída do procedimento “echo”
      • z-async-iterable.ts Helper Zod para subscriptions (somente REST API)
    • Directoryprocedures Procedimentos (ou operações) expostos pela sua API
      • echo.ts Procedimento de exemplo
    • Directorymiddleware
      • error.ts Middleware para tratamento de erros
      • logger.ts middleware para configurar AWS Powertools para logging no Lambda
      • tracer.ts middleware para configurar AWS Powertools para rastreamento no Lambda
      • metrics.ts middleware para configurar AWS Powertools para métricas no Lambda
    • local-server.ts Ponto de entrada do adaptador standalone tRPC para servidor de desenvolvimento local
    • Directoryclient
      • index.ts Cliente type-safe para chamadas máquina-a-máquina na API
  • tsconfig.json Configuração TypeScript
  • project.json Configuração do projeto e targets de build

Como este gerador fornece infraestrutura como código com base no iacProvider escolhido, ele criará um projeto em packages/common que inclui os constructs CDK ou módulos Terraform relevantes.

O projeto comum de infraestrutura como código está estruturado da seguinte forma:

  • Directorypackages/common/constructs
    • Directorysrc
      • Directoryapp/ Constructs para infraestrutura específica de um projeto/gerador
      • Directorycore/ Constructs genéricos reutilizados pelos constructs em app
      • index.ts Ponto de entrada exportando os constructs de app
    • project.json Metas de build e configuração do projeto

Para implantar sua API, os seguintes arquivos são gerados:

  • Directorypackages/common/constructs/src
    • Directoryapp
      • Directoryapis
        • <project-name>.ts Construto CDK para implantar sua API
    • Directorycore
      • Directoryapi
        • http-api.ts Construto CDK para implantar uma API HTTP (se você escolheu implantar uma API HTTP)
        • rest-api.ts Construto CDK para implantar uma API REST (se você escolheu implantar uma API REST)
        • utils.ts Utilitários para os construtos da API

A aplicação implantada possui a seguinte arquitetura:

ClientWAFAPI Gateway(REST API)LambdaCloudWatch(Logs, Metrics)X-Ray(Traces)

As REST APIs incluem uma Web ACL do AWS WAFv2 na frente do estágio do API Gateway com o conjunto de regras padrão gerenciado pela AWS habilitado.

Em alto nível, APIs tRPC consistem em um roteador que delega requisições para procedimentos específicos. Cada procedimento possui uma entrada e saída definidas como schemas Zod.

O diretório src/schema contém os tipos compartilhados entre seu código cliente e servidor. Neste pacote, esses tipos são definidos usando Zod, uma biblioteca de declaração e validação de schemas TypeScript-first.

Um exemplo de schema pode ser:

import { z } from 'zod';
// Definição do schema
export const UserSchema = z.object({
name: z.string(),
height: z.number(),
dateOfBirth: z.string().datetime(),
});
// Tipo TypeScript correspondente
export type User = z.TypeOf<typeof UserSchema>;

Dado o schema acima, o tipo User é equivalente ao seguinte TypeScript:

interface User {
name: string;
height: number;
dateOfBirth: string;
}

Schemas são compartilhados entre código servidor e cliente, provendo um único local para atualizações quando alterar estruturas usadas na sua API.

Schemas são automaticamente validados pela sua API tRPC em runtime, eliminando a necessidade de criar lógica de validação manual no backend.

Zod fornece utilitários poderosos para combinar ou derivar schemas como .merge, .pick, .omit e mais. Mais informações no site de documentação do Zod.

Seu roteador tRPC é definido em src/router.ts, que registra todos os procedimentos. Cada procedimento define a entrada esperada, saída e implementação. O ponto de entrada do handler Lambda está em src/handler.ts, que encaminha requisições para seu roteador.

O roteador de exemplo gerado possui uma única operação chamada echo:

import { echo } from './procedures/echo.js';
export const appRouter = router({
echo,
});

O procedimento echo de exemplo é gerado em src/procedures/echo.ts:

export const echo = publicProcedure
.input(EchoInputSchema)
.output(EchoOutputSchema)
.query((opts) => ({ message: opts.input.message }));

Analisando o código acima:

  • publicProcedure define um método público na API, incluindo middleware configurado em src/middleware. Este middleware inclui integração com AWS Lambda Powertools para logging, rastreamento e métricas.
  • input aceita um schema Zod que define a entrada esperada para a operação. Requisições são automaticamente validadas contra este schema.
  • output aceita um schema Zod que define a saída esperada. Erros de tipo serão exibidos se a implementação não retornar uma saída conforme o schema.
  • query aceita uma função que define a implementação. Recebe opts, que contém o input passado para a operação, além de contexto configurado por middleware disponível em opts.ctx. A função deve retornar uma saída conforme o schema output.

O uso de query indica que a operação não é mutativa. Use para métodos de recuperação de dados. Para operações mutativas, use mutation.

Ao adicionar novos procedimentos, registre-os no roteador em src/router.ts.

infra = rest-lambda

tRPC subscriptions permitem transmitir dados do servidor para o cliente usando Server-Sent Events (SSE). Quando você seleciona rest-lambda como seu tipo de computação, o gerador configura automaticamente a infraestrutura necessária para streaming, bem como um handler Lambda de streaming e o helper de schema ZodAsyncIterable.

Para definir um procedimento de subscription, use o método .subscription com uma função geradora assíncrona. Use o helper ZodAsyncIterable de src/schema/z-async-iterable.ts para definir o schema de saída:

import { publicProcedure } from '../init.js';
import { z } from 'zod';
import { ZodAsyncIterable } from '../schema/z-async-iterable.js';
const InputSchema = z.object({ query: z.string() });
const ChunkSchema = z.object({ text: z.string() });
export const myStream = publicProcedure
.input(InputSchema)
.output(
ZodAsyncIterable({
yield: ChunkSchema,
}),
)
.subscription(async function* (opts) {
// Retorna dados ao cliente conforme ficam disponíveis
for (const chunk of await getResults(opts.input.query)) {
yield { text: chunk };
}
});

Registre a subscription no seu roteador como qualquer outro procedimento:

export const appRouter = router({
echo,
myStream,
});

A infraestrutura gerada usa um handler Lambda de streaming com ResponseTransferMode.STREAM no API Gateway para todas as operações REST API, o que permite que subscriptions funcionem junto com queries e mutations regulares.

Na implementação, você pode retornar erros lançando TRPCError. Estes aceitam um code indicando o tipo de erro, por exemplo:

throw new TRPCError({
code: 'NOT_FOUND',
message: 'O recurso solicitado não foi encontrado',
});

Conforme a API cresce, você pode agrupar operações relacionadas.

Agrupe operações usando roteadores aninhados:

import { getUser } from './procedures/users/get.js';
import { listUsers } from './procedures/users/list.js';
const appRouter = router({
users: router({
get: getUser,
list: listUsers,
}),
...
})

Clientes recebem este agrupamento, por exemplo invocando listUsers:

client.users.list.query();

O logger AWS Lambda Powertools é configurado em src/middleware/logger.ts e acessado via opts.ctx.logger. Use para registrar logs no CloudWatch e/ou controlar valores adicionais em cada mensagem de log. Exemplo:

export const echo = publicProcedure
.input(...)
.output(...)
.query(async (opts) => {
opts.ctx.logger.info('Operação chamada com input', opts.input);
return ...;
});

Para mais informações, consulte a documentação do AWS Lambda Powertools Logger.

Métricas do AWS Lambda Powertools são configuradas em src/middleware/metrics.ts e acessadas via opts.ctx.metrics. Use para registrar métricas no CloudWatch sem necessidade do AWS SDK:

export const echo = publicProcedure
.input(...)
.output(...)
.query(async (opts) => {
opts.ctx.metrics.addMetric('Invocations', 'Count', 1);
return ...;
});

Para mais informações, consulte a documentação do AWS Lambda Powertools Metrics.

O tracer AWS Lambda Powertools é configurado em src/middleware/tracer.ts e acessado via opts.ctx.tracer. Use para adicionar traces com AWS X-Ray:

export const echo = publicProcedure
.input(...)
.output(...)
.query(async (opts) => {
const subSegment = opts.ctx.tracer.getSegment()!.addNewSubsegment('MyAlgorithm');
// ... lógica do algoritmo para capturar
subSegment.close();
return ...;
});

Para mais informações, consulte a documentação do AWS Lambda Powertools Tracer.

Adicione valores ao contexto de procedimentos implementando middleware.

Exemplo: middleware para extrair detalhes do usuário em src/middleware/identity.ts.

auth = iam

Este exemplo demonstra middleware de identidade para autenticação IAM. Buscamos o chamador no Cognito usando o sub extraído do evento do API Gateway.

Primeiro definimos o contexto adicional:

export interface IIdentityContext {
identity?: {
sub: string;
username: string;
};
}

Note que definimos uma propriedade adicional opcional no contexto. tRPC gerencia a garantia de que isso esteja definido em procedimentos que configuraram corretamente este middleware.

Em seguida, implementamos o middleware:

export const createIdentityPlugin = () => {
const t = initTRPC.context<...>().create();
return t.procedure.use(async (opts) => {
// Lógica antes do procedimento
const response = await opts.next(...);
// Lógica após o procedimento
return response;
});
};

No nosso caso, queremos extrair detalhes sobre o usuário Cognito chamador. Faremos isso extraindo o ID de assunto do usuário (ou “sub”) do evento do API Gateway e recuperando detalhes do usuário do Cognito. A implementação varia dependendo se o evento foi fornecido à nossa função por uma REST API ou uma HTTP API:

import { CognitoIdentityProvider } from '@aws-sdk/client-cognito-identity-provider';
import { initTRPC, TRPCError } from '@trpc/server';
import { CreateAWSLambdaContextOptions } from '@trpc/server/adapters/aws-lambda';
import { APIGatewayProxyEvent } from 'aws-lambda';
export interface IIdentityContext {
identity?: {
sub: string;
username: string;
};
}
export const createIdentityPlugin = () => {
const t = initTRPC.context<IIdentityContext & CreateAWSLambdaContextOptions<APIGatewayProxyEvent>>().create();
const cognito = new CognitoIdentityProvider();
return t.procedure.use(async (opts) => {
const cognitoAuthenticationProvider = opts.ctx.event.requestContext?.identity?.cognitoAuthenticationProvider;
let sub: string | undefined = undefined;
if (cognitoAuthenticationProvider) {
const providerParts = cognitoAuthenticationProvider.split(':');
sub = providerParts[providerParts.length - 1];
}
if (!sub) {
throw new TRPCError({
code: 'FORBIDDEN',
message: `Não foi possível determinar o usuário chamador`,
});
}
const { Users } = await cognito.listUsers({
// Assume que o ID do user pool está configurado no ambiente Lambda
UserPoolId: process.env.USER_POOL_ID!,
Limit: 1,
Filter: `sub="${sub}"`,
});
if (!Users || Users.length !== 1) {
throw new TRPCError({
code: 'FORBIDDEN',
message: `Nenhum usuário encontrado com subjectId ${sub}`,
});
}
// Fornece a identidade para outros procedimentos no contexto
return await opts.next({
ctx: {
...opts.ctx,
identity: {
sub,
username: Users[0].Username!,
},
},
});
});
};
auth = cognito

Quando você implanta com auth: 'cognito', o autorizador Cognito User Pools do API Gateway verifica o JWT que o chamador fornece no cabeçalho Authorization e coloca as claims verificadas no evento Lambda em event.requestContext.authorizer.claims. Nosso middleware apenas lê essas claims — sem chamadas extras ao AWS SDK, sem verificação manual de JWT.

Primeiro definimos o que adicionaremos ao contexto:

export interface IIdentityContext {
identity?: {
sub: string;
username: string;
};
}

Note que definimos uma propriedade adicional opcional no contexto. tRPC gerencia a garantia de que isso esteja definido em procedimentos que configuraram corretamente este middleware.

Em seguida, o middleware em si:

import { initTRPC, TRPCError } from '@trpc/server';
import { CreateAWSLambdaContextOptions } from '@trpc/server/adapters/aws-lambda';
import { APIGatewayProxyEvent } from 'aws-lambda';
export interface IIdentityContext {
identity?: {
sub: string;
username: string;
};
}
export const createIdentityPlugin = () => {
const t = initTRPC
.context<IIdentityContext & CreateAWSLambdaContextOptions<APIGatewayProxyEvent>>()
.create();
return t.procedure.use(async (opts) => {
const claims = opts.ctx.event.requestContext?.authorizer?.claims as
| Record<string, string>
| undefined;
const sub = claims?.sub;
const username = claims?.username;
if (!sub || !username) {
throw new TRPCError({
code: 'FORBIDDEN',
message: 'Não foi possível determinar o usuário chamador',
});
}
return await opts.next({
ctx: {
...opts.ctx,
identity: {
sub,
username,
},
},
});
});
};

Você pode então misturar o plugin em qualquer procedimento que precise da identidade do chamador:

import { publicProcedure } from '../init.js';
import { createIdentityPlugin } from '../middleware/identity.js';
import { z } from 'zod';
export const me = publicProcedure
.concat(createIdentityPlugin())
.output(z.object({ sub: z.string(), username: z.string() }))
.query(({ ctx }) => ({
sub: ctx.identity!.sub,
username: ctx.identity!.username,
}));

O gerador cria infraestrutura como código CDK ou Terraform baseado no iacProvider selecionado. Use para implantar sua API.

O construct CDK para implantação está na pasta common/constructs. Você pode consumir isso em uma aplicação CDK, por exemplo:

auth = iam | custom
import { MyApi } from ':my-scope/common-constructs';
export class ExampleStack extends Stack {
constructor(scope: Construct, id: string) {
// Adicione a api ao seu stack
const api = new MyApi(this, 'MyApi', {
integrations: MyApi.defaultIntegrations(this).build(),
});
}
}
auth = cognito
import { MyApi, UserIdentity } from ':my-scope/common-constructs';
export class ExampleStack extends Stack {
constructor(scope: Construct, id: string) {
// Adicione a api ao seu stack
const identity = new UserIdentity(this, 'Identity');
const api = new MyApi(this, 'MyApi', {
integrations: MyApi.defaultIntegrations(this).build(),
identity,
});
}
}

O construct UserIdentity pode ser gerado usando o gerador ts#website#auth.

Isso configura a infraestrutura da sua API, incluindo AWS API Gateway REST ou HTTP API, funções AWS Lambda para lógica de negócio e autenticação baseada no método auth escolhido.

infra = rest-lambda

Para APIs REST, o construto gerado associa um Web ACL do AWS WAFv2 ao estágio do API Gateway por padrão. O Web ACL usa o conjunto de regras padrão gerenciado pela AWS (AWSManagedRulesCommonRuleSet e AWSManagedRulesKnownBadInputsRuleSet), fornecendo proteção contra explorações web comuns, incluindo o OWASP Top 10. Os logs de requisições do WAF são gravados em um grupo do CloudWatch Logs.

Você pode editar o construto rest-api gerado para adicionar, remover ou ajustar regras (por exemplo, para adicionar regras baseadas em taxa ou grupos de regras gerenciadas adicionais).

Para desativar (por exemplo, para anexar seu próprio Web ACL), defina enableWaf como false:

const api = new MyApi(this, 'MyApi', {
integrations: MyApi.defaultIntegrations(this).build(),
enableWaf: false,
});
infra = rest-lambda

Para APIs REST, a infraestrutura gerada habilita o registro de acesso por padrão, escrevendo uma linha JSON estruturada por solicitação em um grupo dedicado do CloudWatch Logs. O grupo de logs é criptografado com uma chave KMS gerenciada pelo cliente e retido por um ano.

O API Gateway escreve logs de acesso usando uma função do CloudWatch Logs no nível da conta. Essa função é configurada na configuração AWS::ApiGateway::Account, que é um singleton por região por conta — há apenas uma função para cada API REST na região. Para gerenciar isso com segurança em várias pilhas implantadas independentemente, a infraestrutura gerada:

  • Cria uma função compartilhada do CloudWatch Logs e a configura na conta somente quando nenhuma função funcional já está definida, para que as implantações nunca substituam uma função que outra pilha possui.
  • Deixa a configuração da conta intocada na desmontagem, para que a destruição de uma pilha nunca desabilite o registro para outras APIs REST na região.

A função da conta é gerenciada pelo construto ApiGatewayAccount, um singleton com escopo de pilha resolvido via ApiGatewayAccount.ensure(scope). O estágio de cada API REST depende dele, e a função é configurada por um recurso personalizado baseado em Lambda.

Você pode personalizar o formato do log de acesso passando deployOptions ao construir sua API:

const api = new MyApi(this, 'MyApi', {
integrations: MyApi.defaultIntegrations(this).build(),
deployOptions: {
accessLogFormat: AccessLogFormat.clf(),
},
});

Os construtos CDK da API REST/HTTP são configurados para fornecer uma interface type-safe para definir integrações para cada uma de suas operações.

Os construtos CDK fornecem suporte completo a integrações type-safe conforme descrito abaixo.

Você pode usar o método estático defaultIntegrations para utilizar o padrão padrão, que define uma função AWS Lambda individual para cada operação:

new MyApi(this, 'MyApi', {
integrations: MyApi.defaultIntegrations(this).build(),
});

Você pode acessar as funções AWS Lambda subjacentes através da propriedade integrations do construto da API, de forma type-safe. Por exemplo, se sua API define uma operação chamada sayHello e você precisa adicionar permissões a esta função, você pode fazer isso da seguinte forma:

const api = new MyApi(this, 'MyApi', {
integrations: MyApi.defaultIntegrations(this).build(),
});
// sayHello é tipado conforme as operações definidas em sua API
api.integrations.sayHello.handler.addToRolePolicy(new PolicyStatement({
effect: Effect.ALLOW,
actions: [...],
resources: [...],
}));

Se sua API usa o padrão shared, o roteador Lambda compartilhado é exposto como api.integrations.$router:

const api = new MyApi(this, 'MyApi', {
integrations: MyApi.defaultIntegrations(this).build(),
});
api.integrations.$router.handler.addEnvironment('LOG_LEVEL', 'DEBUG');

Se você deseja personalizar as opções usadas ao criar a função Lambda para cada integração padrão, pode usar o método withDefaultOptions. Por exemplo, se deseja que todas suas funções Lambda residam em uma VPC:

const vpc = new Vpc(this, 'Vpc', ...);
new MyApi(this, 'MyApi', {
integrations: MyApi.defaultIntegrations(this)
.withDefaultOptions({
vpc,
})
.build(),
});

Para personalizar as opções usadas para criar a integração padrão para operações específicas (sem afetar as outras), você pode usar o método withOperationOptions. Por exemplo, se você deseja aumentar o timeout da função Lambda para apenas uma operação:

const api = new MyApi(this, 'MyApi', {
integrations: MyApi.defaultIntegrations(this)
.withOperationOptions({
sayHello: {
timeout: Duration.seconds(60),
},
})
.build(),
});
// As operações selecionadas permanecem integrações padrão, então ainda são tipadas adequadamente:
api.integrations.sayHello.handler.addToRolePolicy(new PolicyStatement({ ... }));

As opções que você especifica são mescladas com as opções de integração padrão (e quaisquer opções definidas via withDefaultOptions). Note que você não pode especificar opções para operações que você substituiu via withOverrides, pois estas não usam mais a integração padrão.

Você encontrará um erro de tipo se a mesma operação for alvo tanto de withOperationOptions quanto de withOverrides, independentemente da ordem em que você os chamar.

Você também pode sobrescrever integrações para operações específicas usando o método withOverrides. Cada sobrescrita deve especificar uma propriedade integration que é tipada ao construto de integração CDK apropriado para a API HTTP ou REST. O método withOverrides também é type-safe. Por exemplo, se você deseja sobrescrever uma API getDocumentation para apontar para documentação hospedada em um site externo:

new MyApi(this, 'MyApi', {
integrations: MyApi.defaultIntegrations(this)
.withOverrides({
getDocumentation: {
integration: new HttpIntegration('https://example.com/documentation'),
},
})
.build(),
});

Você notará que a integração sobrescrita não terá mais uma propriedade handler quando acessada via api.integrations.getDocumentation.

Você pode adicionar propriedades adicionais a uma integração que também serão tipadas adequadamente, permitindo que outros tipos de integração sejam abstraídos mas permaneçam type-safe. Por exemplo, se você criou uma integração S3 para uma API REST e depois deseja referenciar o bucket para uma operação específica:

const storageBucket = new Bucket(this, 'Bucket', { ... });
const apiGatewayRole = new Role(this, 'ApiGatewayS3Role', {
assumedBy: new ServicePrincipal('apigateway.amazonaws.com'),
});
storageBucket.grantRead(apiGatewayRole);
const api = new MyApi(this, 'MyApi', {
integrations: MyApi.defaultIntegrations(this)
.withOverrides({
getFile: {
bucket: storageBucket,
integration: new AwsIntegration({
service: 's3',
integrationHttpMethod: 'GET',
path: `${storageBucket.bucketName}/{fileName}`,
options: {
credentialsRole: apiGatewayRole,
requestParameters: {
'integration.request.path.fileName': 'method.request.querystring.fileName',
},
integrationResponses: [{ statusCode: '200' }],
},
}),
options: {
requestParameters: {
'method.request.querystring.fileName': true,
},
methodResponses: [{
statusCode: '200',
}],
}
},
})
.build(),
});
// Posteriormente, talvez em outro arquivo, você pode acessar a propriedade bucket que definimos
// de forma type-safe
api.integrations.getFile.bucket.grantRead(...);

Você também pode fornecer options em sua integração para sobrescrever opções específicas de método como autorizadores. Por exemplo, se desejar usar autenticação Cognito para sua operação getDocumentation:

new MyApi(this, 'MyApi', {
integrations: MyApi.defaultIntegrations(this)
.withOverrides({
getDocumentation: {
integration: new HttpIntegration('https://example.com/documentation'),
options: {
authorizer: new CognitoUserPoolsAuthorizer(...) // para REST, ou HttpUserPoolAuthorizer para HTTP API
}
},
})
.build(),
});

Se preferir, você pode optar por não usar as integrações padrão e fornecer diretamente uma para cada operação. Isso é útil se, por exemplo, cada operação precisar usar um tipo diferente de integração ou se você quiser receber um erro de tipo ao adicionar novas operações:

new MyApi(this, 'MyApi', {
integrations: {
sayHello: {
integration: new LambdaIntegration(...),
},
getDocumentation: {
integration: new HttpIntegration(...),
},
},
});

Os construtos CDK de API gerados suportam dois padrões de integração:

  • isolated cria uma função Lambda por operação. Este é o padrão para APIs geradas.
  • shared cria um único roteador Lambda padrão e o reutiliza para cada operação, a menos que você sobrescreva integrações específicas.

isolated oferece permissões e configuração mais granulares por operação. shared reduz a proliferação de funções Lambda e integrações do API Gateway, ainda permitindo sobrescritas seletivas.

Por exemplo, definir pattern como 'shared' cria uma única função em vez de uma por integração:

packages/common/constructs/src/app/apis/my-api.ts
export class MyApi<...> extends ... {
public static defaultIntegrations = (scope: Construct) => {
...
return IntegrationBuilder.rest({
pattern: 'shared',
...
});
};
}
auth = iam

Você pode conceder acesso à sua API da seguinte forma:

api.grantInvokeAccess(myIdentityPool.authenticatedRole);

O gerador configura automaticamente um destino bundle que utiliza o Rolldown para criar um pacote de implantação:

Terminal window
pnpm nx bundle <project-name>

A configuração do Rolldown pode ser encontrada em rolldown.config.ts, com uma entrada para cada pacote a ser gerado. O Rolldown gerencia a criação de múltiplos pacotes em paralelo, se definidos.

Você pode usar o target serve para executar um servidor local para sua API, por exemplo:

Terminal window
pnpm nx serve my-api

O ponto de entrada para o servidor local é src/local-server.ts.

Isso recarregará automaticamente quando você fizer alterações na sua API.

Você pode criar um cliente tRPC para invocar sua API de forma type-safe. Se você está chamando sua API tRPC de outro backend, pode usar o cliente em src/client/index.ts, por exemplo:

import { createMyApiClient } from ':my-scope/my-api';
const client = createMyApiClient({ url: 'https://my-api-url.example.com/' });
await client.echo.query({ message: 'Hello world!' });

Se você está chamando sua API de um website React, considere usar o gerador Connection para configurar o cliente.

Para mais informações sobre tRPC, consulte a documentação do tRPC.

Use o gerador connection para integrar este projeto com outros em seu workspace. As seguintes conexões envolvem este projeto:

tRPC
React para tRPCChame uma API tRPC de um site React
tRPCAmazon Aurora
API tRPC para Banco de Dados RelacionalConecte uma API tRPC a um banco de dados relacional Aurora
tRPCAmazon DynamoDB
API tRPC para TypeScript DynamoDBConecte uma API tRPC a uma tabela DynamoDB