tRPC
tRPC 是一个用于在 TypeScript 中构建端到端类型安全 API 的框架。使用 tRPC 时,API 操作输入输出的更新会立即反映在客户端代码中,并可在 IDE 中直接查看,无需重新构建项目。
tRPC API 生成器会创建一个新的 tRPC API,并配置 AWS CDK 或 Terraform 基础设施。生成的后端使用 AWS Lambda 进行无服务器部署,通过 AWS API Gateway API 暴露,并包含使用 Zod 的模式验证。它配置了 AWS Lambda Powertools 用于可观测性,包括日志记录、AWS X-Ray 追踪和 Cloudwatch 指标。
生成 tRPC API
Section titled “生成 tRPC API”您可以通过两种方式生成新的 tRPC API:
- 安装 Nx Console VSCode Plugin 如果您尚未安装
- 在VSCode中打开Nx控制台
- 点击
Generate (UI)
在"Common Nx Commands"部分 - 搜索
@aws/nx-plugin - ts#trpc-api
- 填写必需参数
- 点击
Generate
pnpm nx g @aws/nx-plugin:ts#trpc-api
yarn nx g @aws/nx-plugin:ts#trpc-api
npx nx g @aws/nx-plugin:ts#trpc-api
bunx nx g @aws/nx-plugin:ts#trpc-api
参数 | 类型 | 默认值 | 描述 |
---|---|---|---|
name 必需 | string | - | The name of the API (required). Used to generate class names and file paths. |
computeType | string | ServerlessApiGatewayRestApi | The type of compute to use to deploy this API. Choose between ServerlessApiGatewayRestApi (default) or ServerlessApiGatewayHttpApi. |
auth | string | IAM | The method used to authenticate with your API. Choose between IAM (default), Cognito or None. |
directory | string | packages | The directory to store the application in. |
iacProvider | string | Inherit | The preferred IaC provider. By default this is inherited from your initial selection. |
生成器将在 <directory>/<api-name>
目录中创建以下项目结构:
文件夹src
- init.ts 后端 tRPC 初始化
- router.ts tRPC 路由定义(Lambda 处理程序 API 入口点)
文件夹schema 使用 Zod 的模式定义
- echo.ts “echo” 过程的输入输出示例定义
文件夹procedures API 暴露的过程(或操作)
- echo.ts 示例过程
文件夹middleware
- error.ts 错误处理中间件
- logger.ts 配置 AWS Lambda Powertools 日志记录的中间件
- tracer.ts 配置 AWS Lambda Powertools 追踪的中间件
- metrics.ts 配置 AWS Lambda Powertools 指标的中间件
- local-server.ts 本地开发服务器使用的 tRPC 独立适配器入口点
文件夹client
- index.ts 用于机器间 API 调用的类型安全客户端
- tsconfig.json TypeScript 配置
- project.json 项目配置和构建目标
由于该生成器会根据您选择的 iacProvider
以基础设施即代码的形式输出,它将在 packages/common
目录下创建一个包含相关 CDK 构造体或 Terraform 模块的项目。
通用的基础设施即代码项目结构如下:
文件夹packages/common/constructs
文件夹src
文件夹app/ 针对特定项目/生成器的基础设施构造体
- …
文件夹core/ 被
app
目录构造体重用的通用构造体- …
- index.ts 导出
app
目录构造体的入口文件
- project.json 项目构建目标与配置
文件夹packages/common/terraform
文件夹src
文件夹app/ 针对特定项目/生成器的 Terraform 模块
- …
文件夹core/ 被
app
目录模块重用的通用模块- …
- project.json 项目构建目标与配置
部署 API 时会生成以下文件:
文件夹packages/common/constructs/src
文件夹app
文件夹apis
- <project-name>.ts 用于部署 API 的 CDK 构造
文件夹core
文件夹api
- http-api.ts 部署 HTTP API 的 CDK 构造(如果你选择部署 HTTP API)
- rest-api.ts 部署 REST API 的 CDK 构造(如果你选择部署 REST API)
- utils.ts API 构造的实用工具
文件夹packages/common/terraform/src
文件夹app
文件夹apis
文件夹<project-name>
- <project-name>.tf 用于部署 API 的 Terraform 模块
文件夹core
文件夹api
文件夹http-api
- http-api.tf 部署 HTTP API 的模块(如果你选择部署 HTTP API)
文件夹rest-api
- rest-api.tf 部署 REST API 的模块(如果你选择部署 REST API)
实现 tRPC API
Section titled “实现 tRPC API”从高层次来看,tRPC API 由将请求委托给特定过程的路由器组成。每个过程都有使用 Zod 模式定义的输入和输出。
src/schema
目录包含客户端和服务器代码共享的类型。在本包中,这些类型使用 Zod(一个 TypeScript 优先的模式声明和验证库)定义。
示例模式可能如下所示:
import { z } from 'zod';
// 模式定义export const UserSchema = z.object({ name: z.string(), height: z.number(), dateOfBirth: z.string().datetime(),});
// 对应的 TypeScript 类型export type User = z.TypeOf<typeof UserSchema>;
根据上述模式,User
类型等效于以下 TypeScript:
interface User { name: string; height: number; dateOfBirth: string;}
模式在服务器和客户端代码之间共享,当需要修改 API 使用的结构时,只需在此处更新即可。
tRPC API 在运行时自动验证模式,无需在后端手工编写验证逻辑。
Zod 提供了强大的工具来组合或派生模式,如 .merge
、.pick
、.omit
等。更多信息请参阅 Zod 文档网站。
您可以在 src/router.ts
中找到 API 的入口点。该文件包含 Lambda 处理程序,根据调用的操作将请求路由到”过程”。每个过程定义预期的输入、输出和实现。
生成的示例路由器有一个名为 echo
的单一操作:
import { echo } from './procedures/echo.js';
export const appRouter = router({ echo,});
示例 echo
过程在 src/procedures/echo.ts
中生成:
export const echo = publicProcedure .input(EchoInputSchema) .output(EchoOutputSchema) .query((opts) => ({ result: opts.input.message }));
分解上述代码:
publicProcedure
定义 API 的公共方法,包含在src/middleware
中设置的中间件。该中间件包括用于日志记录、追踪和指标的 AWS Lambda Powertools 集成input
接受定义操作预期输入的 Zod 模式。发送到此操作的请求会自动根据此模式验证output
接受定义操作预期输出的 Zod 模式。如果返回不符合模式的输出,实现中会出现类型错误query
接受定义 API 实现的函数。该实现接收包含操作输入的opts
,以及中间件设置的上下文(通过opts.ctx
访问)。传递给query
的函数必须返回符合output
模式的输出
使用 query
定义实现表示该操作是非变更性的。使用此方法来定义数据检索方法。要实现变更性操作,请改用 mutation
方法。
如果添加新过程,请确保在 src/router.ts
的路由器中注册它。
自定义 tRPC API
Section titled “自定义 tRPC API”在实现中,您可以通过抛出 TRPCError
向客户端返回错误响应。这些错误接受表示错误类型的 code
,例如:
throw new TRPCError({ code: 'NOT_FOUND', message: '找不到请求的资源',});
随着 API 的增长,您可能希望将相关操作分组。
您可以使用嵌套路由器对操作进行分组,例如:
import { getUser } from './procedures/users/get.js';import { listUsers } from './procedures/users/list.js';
const appRouter = router({ users: router({ get: getUser, list: listUsers, }), ...})
客户端将接收此操作分组,例如在此情况下调用 listUsers
操作可能如下所示:
client.users.list.query();
AWS Lambda Powertools 日志记录器在 src/middleware/logger.ts
中配置,可通过 opts.ctx.logger
在 API 实现中访问。您可以使用此记录器向 CloudWatch Logs 记录日志,并/或控制每个结构化日志消息中包含的额外值。例如:
export const echo = publicProcedure .input(...) .output(...) .query(async (opts) => { opts.ctx.logger.info('操作调用输入', opts.input);
return ...; });
有关日志记录器的更多信息,请参阅 AWS Lambda Powertools 日志记录器文档。
AWS Lambda Powertools 指标在 src/middleware/metrics.ts
中配置,可通过 opts.ctx.metrics
在 API 实现中访问。您可以使用此功能在 CloudWatch 中记录指标,而无需导入和使用 AWS SDK,例如:
export const echo = publicProcedure .input(...) .output(...) .query(async (opts) => { opts.ctx.metrics.addMetric('Invocations', 'Count', 1);
return ...; });
更多信息请参阅 AWS Lambda Powertools 指标文档。
微调 X-Ray 追踪
Section titled “微调 X-Ray 追踪”AWS Lambda Powertools 追踪器在 src/middleware/tracer.ts
中配置,可通过 opts.ctx.tracer
在 API 实现中访问。您可以使用此功能添加 AWS X-Ray 追踪,以提供 API 请求性能和流程的详细洞察。例如:
export const echo = publicProcedure .input(...) .output(...) .query(async (opts) => { const subSegment = opts.ctx.tracer.getSegment()!.addNewSubsegment('MyAlgorithm'); // ... 要捕获的算法逻辑 subSegment.close();
return ...; });
更多信息请参阅 AWS Lambda Powertools 追踪器文档。
实现自定义中间件
Section titled “实现自定义中间件”您可以通过实现中间件向过程提供的上下文中添加额外值。
例如,让我们在 src/middleware/identity.ts
中实现一些中间件来从 API 中提取调用用户的详细信息。
此示例假设 auth
设置为 IAM
。对于 Cognito 身份验证,身份中间件更简单,直接从 event
中提取相关声明。
首先,我们定义要添加到上下文中的内容:
export interface IIdentityContext { identity?: { sub: string; username: string; };}
注意,我们向上下文定义了一个额外的 可选 属性。tRPC 会管理确保在正确配置此中间件的过程中有此定义。
接下来,我们将实现中间件本身。其结构如下:
export const createIdentityPlugin = () => { const t = initTRPC.context<...>().create(); return t.procedure.use(async (opts) => { // 在此添加过程前运行的逻辑
const response = await opts.next(...);
// 在此添加过程后运行的逻辑
return response; });};
在我们的案例中,我们希望提取调用 Cognito 用户的详细信息。我们将通过从 API Gateway 事件中提取用户的主题 ID(或 “sub”),并从 Cognito 检索用户详细信息来实现。具体实现根据事件是由 REST API 还是 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: `无法确定调用用户`, }); }
const { Users } = await cognito.listUsers({ // 假设用户池 ID 在 Lambda 环境中配置 UserPoolId: process.env.USER_POOL_ID!, Limit: 1, Filter: `sub="${sub}"`, });
if (!Users || Users.length !== 1) { throw new TRPCError({ code: 'FORBIDDEN', message: `找不到主题 ID 为 ${sub} 的用户`, }); }
// 向其他过程提供身份信息 return await opts.next({ ctx: { ...opts.ctx, identity: { sub, username: Users[0].Username!, }, }, }); });};
import { CognitoIdentityProvider } from '@aws-sdk/client-cognito-identity-provider';import { initTRPC, TRPCError } from '@trpc/server';import { CreateAWSLambdaContextOptions } from '@trpc/server/adapters/aws-lambda';import { APIGatewayProxyEventV2WithIAMAuthorizer } from 'aws-lambda';
export interface IIdentityContext { identity?: { sub: string; username: string; };}
export const createIdentityPlugin = () => { const t = initTRPC.context<IIdentityContext & CreateAWSLambdaContextOptions<APIGatewayProxyEventV2WithIAMAuthorizer>>().create();
const cognito = new CognitoIdentityProvider();
return t.procedure.use(async (opts) => { const cognitoIdentity = opts.ctx.event.requestContext?.authorizer?.iam ?.cognitoIdentity as unknown as | { amr: string[]; } | undefined;
const sub = (cognitoIdentity?.amr ?? []) .flatMap((s) => (s.includes(':CognitoSignIn:') ? [s] : [])) .map((s) => { const parts = s.split(':'); return parts[parts.length - 1]; })?.[0];
if (!sub) { throw new TRPCError({ code: 'FORBIDDEN', message: `无法确定调用用户`, }); }
const { Users } = await cognito.listUsers({ // 假设用户池 ID 在 Lambda 环境中配置 UserPoolId: process.env.USER_POOL_ID!, Limit: 1, Filter: `sub="${sub}"`, });
if (!Users || Users.length !== 1) { throw new TRPCError({ code: 'FORBIDDEN', message: `找不到主题 ID 为 ${sub} 的用户`, }); }
// 向其他过程提供身份信息 return await opts.next({ ctx: { ...opts.ctx, identity: { sub, username: Users[0].Username!, }, }, }); });};
部署 tRPC API
Section titled “部署 tRPC API”tRPC API 生成器根据您选择的 iacProvider
创建 CDK 或 Terraform 基础设施即代码。您可以使用此代码部署 tRPC API。
common/constructs
文件夹中包含用于部署 API 的 CDK 构造。您可以在 CDK 应用程序中使用此构造,例如:
import { MyApi } from ':my-scope/common-constructs`;
export class ExampleStack extends Stack { constructor(scope: Construct, id: string) { // 将 API 添加到堆栈 const api = new MyApi(this, 'MyApi', { integrations: MyApi.defaultIntegrations(this).build(), }); }}
这将设置您的 API 基础设施,包括 AWS API Gateway REST 或 HTTP API、用于业务逻辑的 AWS Lambda 函数,以及根据您选择的 auth
方法配置的身份验证。
common/terraform
文件夹中包含用于部署 API 的 Terraform 模块。您可以在 Terraform 配置中使用此模块:
module "my_api" { source = "../../common/terraform/src/app/apis/my-api"
# Lambda 函数的环境变量 env = { ENVIRONMENT = var.environment LOG_LEVEL = "INFO" }
# 如果需要额外的 IAM 策略 additional_iam_policy_statements = [ # 添加 API 需要的额外权限 ]
tags = local.common_tags}
这将设置:
- 服务所有 tRPC 过程的 AWS Lambda 函数
- 作为函数触发器的 API Gateway HTTP/REST API
- IAM 角色和权限
- CloudWatch 日志组
- X-Ray 追踪配置
- CORS 配置
Terraform 模块提供多个输出供您使用:
# 访问 API 端点output "api_url" { value = module.my_api.stage_invoke_url}
# 访问 Lambda 函数详情output "lambda_function_name" { value = module.my_api.lambda_function_name}
# 访问用于授予额外权限的 IAM 角色output "lambda_execution_role_arn" { value = module.my_api.lambda_execution_role_arn}
您可以通过传递变量自定义 CORS 设置:
module "my_api" { source = "../../common/terraform/src/app/apis/my-api"
# 自定义 CORS 配置 cors_allow_origins = ["https://myapp.com", "https://staging.myapp.com"] cors_allow_methods = ["GET", "POST", "PUT", "DELETE"] cors_allow_headers = [ "authorization", "content-type", "x-custom-header" ]
tags = local.common_tags}
REST/HTTP API 的 CDK 构造被配置为提供类型安全接口,用于为每个操作定义集成。
您可以使用静态方法 defaultIntegrations
来应用默认模式,这会为每个操作定义独立的 AWS Lambda 函数:
new MyApi(this, 'MyApi', { integrations: MyApi.defaultIntegrations(this).build(),});
Terraform 模块自动使用路由模式与单个 Lambda 函数,无需额外配置:
module "my_api" { source = "../../common/terraform/src/app/apis/my-api"
# 模块自动创建处理所有 API 操作的 # 单个 Lambda 函数 tags = local.common_tags}
您可以通过 API 构造的 integrations
属性以类型安全的方式访问底层 AWS Lambda 函数。例如,如果您的 API 定义了名为 sayHello
的操作,并需要为此函数添加权限:
const api = new MyApi(this, 'MyApi', { integrations: MyApi.defaultIntegrations(this).build(),});
// sayHello 的类型与 API 中定义的操作相匹配api.integrations.sayHello.handler.addToRolePolicy(new PolicyStatement({ effect: Effect.ALLOW, actions: [...], resources: [...],}));
在 Terraform 的路由模式下,只有一个 Lambda 函数。可通过模块输出来访问:
# 为单个 Lambda 函数授予额外权限resource "aws_iam_role_policy" "additional_permissions" { name = "additional-api-permissions" role = module.my_api.lambda_execution_role_name
policy = jsonencode({ Version = "2012-10-17" Statement = [ { Effect = "Allow" Action = [ "s3:GetObject", "s3:PutObject" ] Resource = "arn:aws:s3:::my-bucket/*" } ] })}
自定义默认选项
Section titled “自定义默认选项”如需自定义创建 Lambda 函数时的默认选项,可使用 withDefaultOptions
方法。例如为所有 Lambda 函数配置 VPC:
const vpc = new Vpc(this, 'Vpc', ...);
new MyApi(this, 'MyApi', { integrations: MyApi.defaultIntegrations(this) .withDefaultOptions({ vpc, }) .build(),});
要自定义 VPC 等配置,需要修改生成的 Terraform 模块。例如为所有 Lambda 函数添加 VPC 支持:
# 添加 VPC 变量variable "vpc_subnet_ids" { description = "Lambda 函数的 VPC 子网 ID 列表" type = list(string) default = []}
variable "vpc_security_group_ids" { description = "Lambda 函数的 VPC 安全组 ID 列表" type = list(string) default = []}
# 更新 Lambda 函数资源resource "aws_lambda_function" "api_lambda" { # ... 现有配置 ...
# 添加 VPC 配置 vpc_config { subnet_ids = var.vpc_subnet_ids security_group_ids = var.vpc_security_group_ids }}
使用带 VPC 配置的模块:
module "my_api" { source = "../../common/terraform/src/app/apis/my-api"
# VPC 配置 vpc_subnet_ids = [aws_subnet.private_a.id, aws_subnet.private_b.id] vpc_security_group_ids = [aws_security_group.lambda_sg.id]
tags = local.common_tags}
使用 withOverrides
方法可以覆盖特定操作的集成。每个覆盖必须指定类型正确的 integration
属性。例如将 getDocumentation
API 指向外部网站:
new MyApi(this, 'MyApi', { integrations: MyApi.defaultIntegrations(this) .withOverrides({ getDocumentation: { integration: new HttpIntegration('https://example.com/documentation'), }, }) .build(),});
覆盖后的集成通过 api.integrations.getDocumentation
访问时将不再具有 handler
属性。
您可以为集成添加额外属性以实现类型安全的抽象。例如为 REST API 创建 S3 集成后引用存储桶:
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(),});
// 后续可类型安全地访问我们定义的 bucket 属性api.integrations.getFile.bucket.grantRead(...);
可在集成中提供 options
来覆盖特定方法选项,例如为 getDocumentation
操作使用 Cognito 认证:
new MyApi(this, 'MyApi', { integrations: MyApi.defaultIntegrations(this) .withOverrides({ getDocumentation: { integration: new HttpIntegration('https://example.com/documentation'), options: { authorizer: new CognitoUserPoolsAuthorizer(...) // REST API 使用,HTTP API 使用 HttpUserPoolAuthorizer } }, }) .build(),});
您可以选择不使用默认集成,直接为每个操作提供集成。这在需要不同集成类型时非常有用:
new MyApi(this, 'MyApi', { integrations: { sayHello: { integration: new LambdaIntegration(...), }, getDocumentation: { integration: new HttpIntegration(...), }, },});
在 Terraform 中实现显式集成,需修改生成的模块:
- 移除默认代理路由(如
resource "aws_apigatewayv2_route" "proxy_routes"
) - 替换单个 Lambda 函数为各操作独立函数
- 为每个操作创建具体集成和路由,复用相同 ZIP 包:
# 移除默认 Lambda 函数和代理集成 resource "aws_lambda_function" "api_lambda" { ... } resource "aws_apigatewayv2_integration" "lambda_integration" { ... } resource "aws_apigatewayv2_route" "proxy_routes" { ... }
# 添加各操作独立 Lambda 函数 resource "aws_lambda_function" "say_hello_handler" { handler = "sayHello.handler" # 特定操作处理器 ... }
resource "aws_lambda_function" "get_documentation_handler" { handler = "getDocumentation.handler" ... }
# 添加具体集成和路由 resource "aws_apigatewayv2_integration" "say_hello_integration" { ... } resource "aws_apigatewayv2_route" "say_hello_route" { ... } resource "aws_apigatewayv2_integration" "get_documentation_integration" { ... } resource "aws_apigatewayv2_route" "get_documentation_route" { ... }
# 添加 Lambda 权限 resource "aws_lambda_permission" "say_hello_permission" { ... } resource "aws_lambda_permission" "get_documentation_permission" { ... }
# 移除默认配置 resource "aws_lambda_function" "api_lambda" { ... } resource "aws_apigatewayv2_integration" "lambda_integration" { ... } resource "aws_apigatewayv2_route" "proxy_routes" { ... }
# 添加各操作资源和集成 resource "aws_api_gateway_resource" "say_hello_resource" { ... } resource "aws_api_gateway_method" "say_hello_method" { ... } resource "aws_api_gateway_integration" "say_hello_integration" { ... }
resource "aws_api_gateway_resource" "get_documentation_resource" { ... } resource "aws_api_gateway_method" "get_documentation_method" { ... } resource "aws_api_gateway_integration" "get_documentation_integration" { ... }
# 更新部署依赖~ resource "aws_api_gateway_deployment" "api_deployment" { depends_on = [ aws_api_gateway_integration.say_hello_integration, aws_api_gateway_integration.get_documentation_integration, ] }
# 添加 Lambda 权限 resource "aws_lambda_permission" "say_hello_permission" { ... } resource "aws_lambda_permission" "get_documentation_permission" { ... }
如需部署单个 Lambda 函数处理所有请求,可修改 defaultIntegrations
方法:
export class MyApi<...> extends ... {
public static defaultIntegrations = (scope: Construct) => { const router = new Function(scope, 'RouterHandler', { ... }); return IntegrationBuilder.rest({ ... buildDefaultIntegration: (op) => { return { // 所有集成引用同一个路由处理器 integration: new LambdaIntegration(router), }; }, }); };}
Terraform 模块默认使用路由模式,自动创建处理所有操作的单个 Lambda 函数:
module "my_api" { source = "../../common/terraform/src/app/apis/my-api"
tags = local.common_tags}
授予访问权限(仅限 IAM)
Section titled “授予访问权限(仅限 IAM)”如果选择使用 IAM
身份验证,可以授予 API 访问权限:
api.grantInvokeAccess(myIdentityPool.authenticatedRole);
# 创建允许调用 API 的 IAM 策略resource "aws_iam_policy" "api_invoke_policy" { name = "MyApiInvokePolicy" description = "允许调用 tRPC API 的策略"
policy = jsonencode({ Version = "2012-10-17" Statement = [ { Effect = "Allow" Action = "execute-api:Invoke" Resource = "${module.my_api.api_execution_arn}/*/*" } ] })}
# 将策略附加到 IAM 角色(例如已验证用户角色)resource "aws_iam_role_policy_attachment" "api_invoke_access" { role = aws_iam_role.authenticated_user_role.name policy_arn = aws_iam_policy.api_invoke_policy.arn}
# 或按名称附加到现有角色resource "aws_iam_role_policy_attachment" "api_invoke_access_existing" { role = "MyExistingRole" policy_arn = aws_iam_policy.api_invoke_policy.arn}
API 模块的关键输出可用于 IAM 策略:
module.my_api.api_execution_arn
- 用于授予 execute-api:Invoke 权限module.my_api.api_arn
- API Gateway ARNmodule.my_api.lambda_function_arn
- Lambda 函数 ARN
生成器会自动配置一个使用 Rolldown 创建部署包的 bundle
目标:
pnpm nx run <project-name>:bundle
yarn nx run <project-name>:bundle
npx nx run <project-name>:bundle
bunx nx run <project-name>:bundle
Rolldown 配置位于 rolldown.config.ts
文件中,每个要生成的包都有对应的入口配置。如果定义了多个包,Rolldown 会并行管理这些包的创建过程。
本地 tRPC 服务器
Section titled “本地 tRPC 服务器”您可以使用 serve
目标运行 API 的本地服务器,例如:
pnpm nx run @my-scope/my-api:serve
yarn nx run @my-scope/my-api:serve
npx nx run @my-scope/my-api:serve
bunx nx run @my-scope/my-api:serve
本地服务器的入口点是 src/local-server.ts
。
当对 API 进行更改时,此服务器会自动重新加载。
调用 tRPC API
Section titled “调用 tRPC API”您可以创建 tRPC 客户端以类型安全的方式调用 API。如果从其他后端调用 tRPC API,可以使用 src/client/index.ts
中的客户端,例如:
import { createMyApiClient } from ':my-scope/my-api';
const client = createMyApiClient({ url: 'https://my-api-url.example.com/' });
await client.echo.query({ message: 'Hello world!' });
如果从 React 网站调用 API,请考虑使用 API 连接 生成器来配置客户端。
有关 tRPC 的更多信息,请参阅 tRPC 文档。