tRPC
tRPC は、エンドツーエンドの型安全性を備えた TypeScript での API 構築フレームワークです。tRPC を使用すると、API 操作の入力と出力の更新が即座にクライアントコードに反映され、プロジェクトの再ビルドなしに IDE 上で可視化されます。
tRPC API ジェネレータは、AWS CDK または Terraform のインフラストラクチャ設定を備えた新しい tRPC API を作成します。生成されるバックエンドはサーバーレスデプロイに AWS Lambda を使用し、AWS API Gateway API を介して公開され、Zod を使用したスキーマ検証が含まれます。また、ロギング、AWS X-Ray トレーシング、Cloudwatch メトリクスを含むオブザーバビリティのために AWS Lambda Powertools が設定されます。
tRPC API の生成
Section titled “tRPC API の生成”新しい tRPC API は2つの方法で生成できます:
- インストール 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. |
ジェネレータの出力
Section titled “ジェネレータの出力”ジェネレータは <directory>/<api-name>
ディレクトリに以下のプロジェクト構造を作成します:
Directorysrc
- init.ts バックエンド tRPC の初期化
- router.ts tRPC ルーター定義(Lambda ハンドラーの API エントリーポイント)
Directoryschema Zod を使用したスキーマ定義
- echo.ts 「echo」プロシージャの入力と出力の例
Directoryprocedures API が公開するプロシージャ(操作)
- echo.ts サンプルプロシージャ
Directorymiddleware
- error.ts エラーハンドリング用ミドルウェア
- logger.ts AWS Powertools のロギング設定用ミドルウェア
- tracer.ts AWS Powertools のトレーシング設定用ミドルウェア
- metrics.ts AWS Powertools のメトリクス設定用ミドルウェア
- local-server.ts ローカル開発サーバー用 tRPC スタンドアロンアダプターエントリーポイント
Directoryclient
- index.ts マシン間 API 呼び出し用型安全クライアント
- tsconfig.json TypeScript 設定
- project.json プロジェクト設定とビルドターゲット
インフラストラクチャ
Section titled “インフラストラクチャ”このジェネレータは選択した iacProvider
に基づいてInfrastructure as Codeを生成するため、packages/common
に関連するCDKコンストラクトまたはTerraformモジュールを含むプロジェクトを作成します。
共通のInfrastructure as Codeプロジェクトは以下の構造を持ちます:
Directorypackages/common/constructs
Directorysrc
Directoryapp/ プロジェクト/ジェネレータ固有のインフラストラクチャ用コンストラクト
- …
Directorycore/
app
内のコンストラクトで再利用される汎用コンストラクト- …
- index.ts
app
からコンストラクトをエクスポートするエントリーポイント
- project.json プロジェクトのビルドターゲットと設定
Directorypackages/common/terraform
Directorysrc
Directoryapp/ プロジェクト/ジェネレータ固有のインフラストラクチャ用Terraformモジュール
- …
Directorycore/
app
内のモジュールで再利用される汎用モジュール- …
- project.json プロジェクトのビルドターゲットと設定
APIをデプロイするために、以下のファイルが生成されます:
Directorypackages/common/constructs/src
Directoryapp
Directoryapis
- <project-name>.ts APIをデプロイするためのCDKコンストラクト
Directorycore
Directoryapi
- http-api.ts HTTP APIをデプロイするCDKコンストラクト(HTTP APIをデプロイする選択をした場合)
- rest-api.ts REST APIをデプロイするCDKコンストラクト(REST APIをデプロイする選択をした場合)
- utils.ts APIコンストラクト用のユーティリティ
Directorypackages/common/terraform/src
Directoryapp
Directoryapis
Directory<project-name>
- <project-name>.tf APIをデプロイするためのモジュール
Directorycore
Directoryapi
Directoryhttp-api
- http-api.tf HTTP APIをデプロイするモジュール(HTTP APIをデプロイする選択をした場合)
Directoryrest-api
- rest-api.tf REST APIをデプロイするモジュール(REST APIをデプロイする選択をした場合)
tRPC API の実装
Section titled “tRPC API の実装”大まかに言うと、tRPC API はリクエストを特定のプロシージャに委譲するルーターで構成されます。各プロシージャには Zod スキーマで定義された入力と出力があります。
src/schema
ディレクトリには、クライアントとサーバーコード間で共有される型が含まれます。これらは TypeScript ファーストのスキーマ宣言および検証ライブラリである Zod を使用して定義されます。
スキーマの例:
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 公式ドキュメント を参照してください。
ルーターとプロシージャ
Section titled “ルーターとプロシージャ”API のエントリーポイントは src/router.ts
にあります。このファイルには、呼び出される操作に基づいてリクエストを「プロシージャ」にルーティングする 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
はsrc/middleware
に設定されたミドルウェアを含む API の公開メソッドを定義input
は操作の期待される入力を定義する Zod スキーマを受け入れるoutput
は操作の期待される出力を定義する Zod スキーマを受け入れるquery
は API の実装を定義する関数を受け入れる。opts
には操作に渡された入力と、opts.ctx
でミドルウェアが設定したコンテキストが含まれる
query
の使用は操作が非変異的であることを示します。データ取得メソッドの定義に使用します。変異操作には mutation
メソッドを使用します。
新しいプロシージャを追加する場合は、src/router.ts
のルーターに登録してください。
tRPC API のカスタマイズ
Section titled “tRPC API のカスタマイズ”実装では、TRPCError
をスローしてクライアントにエラーレスポンスを返せます:
throw new TRPCError({ code: 'NOT_FOUND', message: 'The requested resource could not be found',});
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
経由で実装内でアクセス可能です:
export const echo = publicProcedure .input(...) .output(...) .query(async (opts) => { opts.ctx.logger.info('Operation called with input', opts.input);
return ...; });
詳細は AWS Lambda Powertools Logger ドキュメント を参照。
メトリクス記録
Section titled “メトリクス記録”AWS Lambda Powertools メトリクスは src/middleware/metrics.ts
で設定され、opts.ctx.metrics
経由でアクセス可能です:
export const echo = publicProcedure .input(...) .output(...) .query(async (opts) => { opts.ctx.metrics.addMetric('Invocations', 'Count', 1);
return ...; });
詳細は AWS Lambda Powertools Metrics ドキュメント を参照。
X-Ray トレーシングの微調整
Section titled “X-Ray トレーシングの微調整”AWS Lambda Powertools トレーサーは src/middleware/tracer.ts
で設定され、opts.ctx.tracer
経由でアクセス可能です:
export const echo = publicProcedure .input(...) .output(...) .query(async (opts) => { const subSegment = opts.ctx.tracer.getSegment()!.addNewSubsegment('MyAlgorithm'); // ... トレース対象のアルゴリズムロジック subSegment.close();
return ...; });
詳細は AWS Lambda Powertools Tracer ドキュメント を参照。
カスタムミドルウェアの実装
Section titled “カスタムミドルウェアの実装”コンテキストに追加の値を提供するミドルウェアを実装できます。
例: src/middleware/identity.ts
に API 呼び出し元の詳細を抽出するミドルウェアを実装:
この例は auth
が IAM
に設定されていることを想定。Cognito 認証の場合、event
から関連クレームを抽出可能
コンテキストに追加する内容を定義:
export interface IIdentityContext { identity?: { sub: string; username: string; };}
ミドルウェア実装の構造:
export const createIdentityPlugin = () => { const t = initTRPC.context<...>().create(); return t.procedure.use(async (opts) => { // プロシージャ実行前のロジック
const response = await opts.next(...);
// プロシージャ実行後のロジック
return response; });};
// REST API 向け実装(原文のコードを保持)
// HTTP API 向け実装(原文のコードを保持)
tRPC API のデプロイ
Section titled “tRPC API のデプロイ”tRPC API ジェネレータは選択した iacProvider
に基づき CDK または Terraform の IaC を生成します。
インテグレーション
Section titled “インテグレーション”REST/HTTP API CDKコンストラクトは、各オペレーションの統合を定義するための型安全なインターフェースを提供するように設定されています。
デフォルト統合
Section titled “デフォルト統合”静的メソッド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}
統合へのアクセス
Section titled “統合へのアクセス”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}
統合のオーバーライド
Section titled “統合のオーバーライド”withOverrides
メソッドを使用して特定のオペレーションの統合をオーバーライドできます。各オーバーライドは、HTTPまたはREST APIに適したCDK統合コンストラクトに型付けされた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(...);
オーソライザーのオーバーライド
Section titled “オーソライザーのオーバーライド”統合に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用、HTTP APIの場合はHttpUserPoolAuthorizer } }, }) .build(),});
必要に応じて、デフォルト統合を使用せずに各オペレーションに直接統合を指定できます。例えば、オペレーションごとに異なる統合タイプを使用する場合や、新しいオペレーション追加時に型エラーを受け取りたい場合に有用です:
new MyApi(this, 'MyApi', { integrations: { sayHello: { integration: new LambdaIntegration(...), }, getDocumentation: { integration: new HttpIntegration(...), }, },});
Terraformで明示的なオペレーションごとの統合を行うには、生成されたアプリ固有モジュールを修正してデフォルトのプロキシ統合を置き換えます。
packages/common/terraform/src/app/apis/my-api/my-api.tf
を編集:
- デフォルトのプロキシルートを削除(例:
resource "aws_apigatewayv2_route" "proxy_routes"
) - 単一Lambda関数を個別関数で置き換え
- オペレーションごとに特定の統合とルートを作成(同じZIPバンドルを再利用)
# デフォルトの単一Lambda関数を削除 resource "aws_lambda_function" "api_lambda" { filename = data.archive_file.lambda_zip.output_path function_name = "MyApiHandler" role = aws_iam_role.lambda_execution_role.arn handler = "index.handler" runtime = "nodejs22.x" timeout = 30 # ... その他の設定 }
# デフォルトのプロキシ統合を削除 resource "aws_apigatewayv2_integration" "lambda_integration" { api_id = module.http_api.api_id integration_type = "AWS_PROXY" integration_uri = aws_lambda_function.api_lambda.invoke_arn # ... その他の設定 }
# デフォルトのプロキシルートを削除 resource "aws_apigatewayv2_route" "proxy_routes" { for_each = toset(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD"]) api_id = module.http_api.api_id route_key = "${each.key} /{proxy+}" target = "integrations/${aws_apigatewayv2_integration.lambda_integration.id}" # ... その他の設定 }
# 同じバンドルを使用してオペレーションごとに個別Lambda関数を追加 resource "aws_lambda_function" "say_hello_handler" { filename = data.archive_file.lambda_zip.output_path function_name = "MyApi-SayHello" role = aws_iam_role.lambda_execution_role.arn handler = "sayHello.handler" # このオペレーション用の特定ハンドラ runtime = "nodejs22.x" timeout = 30 source_code_hash = data.archive_file.lambda_zip.output_base64sha256
tracing_config { mode = "Active" }
environment { variables = merge({ AWS_CONNECTION_REUSE_ENABLED = "1" }, var.env) }
tags = var.tags }
resource "aws_lambda_function" "get_documentation_handler" { filename = data.archive_file.lambda_zip.output_path function_name = "MyApi-GetDocumentation" role = aws_iam_role.lambda_execution_role.arn handler = "getDocumentation.handler" # このオペレーション用の特定ハンドラ runtime = "nodejs22.x" timeout = 30 source_code_hash = data.archive_file.lambda_zip.output_base64sha256
tracing_config { mode = "Active" }
environment { variables = merge({ AWS_CONNECTION_REUSE_ENABLED = "1" }, var.env) }
tags = var.tags }
# オペレーションごとに特定の統合を追加 resource "aws_apigatewayv2_integration" "say_hello_integration" { api_id = module.http_api.api_id integration_type = "AWS_PROXY" integration_uri = aws_lambda_function.say_hello_handler.invoke_arn payload_format_version = "2.0" timeout_milliseconds = 30000 }
resource "aws_apigatewayv2_integration" "get_documentation_integration" { api_id = module.http_api.api_id integration_type = "HTTP_PROXY" integration_uri = "https://example.com/documentation" integration_method = "GET" }
# オペレーションごとに特定のルートを追加 resource "aws_apigatewayv2_route" "say_hello_route" { api_id = module.http_api.api_id route_key = "POST /sayHello" target = "integrations/${aws_apigatewayv2_integration.say_hello_integration.id}" authorization_type = "AWS_IAM" }
resource "aws_apigatewayv2_route" "get_documentation_route" { api_id = module.http_api.api_id route_key = "GET /documentation" target = "integrations/${aws_apigatewayv2_integration.get_documentation_integration.id}" authorization_type = "NONE" }
# 各関数にLambda権限を追加 resource "aws_lambda_permission" "say_hello_permission" { statement_id = "AllowExecutionFromAPIGateway-SayHello" action = "lambda:InvokeFunction" function_name = aws_lambda_function.say_hello_handler.function_name principal = "apigateway.amazonaws.com" source_arn = "${module.http_api.api_execution_arn}/*/*" }
resource "aws_lambda_permission" "get_documentation_permission" { statement_id = "AllowExecutionFromAPIGateway-GetDocumentation" action = "lambda:InvokeFunction" function_name = aws_lambda_function.get_documentation_handler.function_name principal = "apigateway.amazonaws.com" source_arn = "${module.http_api.api_execution_arn}/*/*" }
# デフォルトの単一Lambda関数を削除 resource "aws_lambda_function" "api_lambda" { filename = data.archive_file.lambda_zip.output_path function_name = "MyApiHandler" role = aws_iam_role.lambda_execution_role.arn handler = "index.handler" runtime = "nodejs22.x" timeout = 30 # ... その他の設定 }
# デフォルトのプロキシ統合を削除 resource "aws_apigatewayv2_integration" "lambda_integration" { api_id = module.http_api.api_id integration_type = "AWS_PROXY" integration_uri = aws_lambda_function.api_lambda.invoke_arn # ... その他の設定 }
# デフォルトのプロキシルートを削除 resource "aws_apigatewayv2_route" "proxy_routes" { for_each = toset(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD"]) api_id = module.http_api.api_id route_key = "${each.key} /{proxy+}" target = "integrations/${aws_apigatewayv2_integration.lambda_integration.id}" # ... その他の設定 }
# 同じバンドルを使用してオペレーションごとに個別Lambda関数を追加 resource "aws_lambda_function" "say_hello_handler" { filename = data.archive_file.lambda_zip.output_path function_name = "MyApi-SayHello" role = aws_iam_role.lambda_execution_role.arn handler = "sayHello.handler" # このオペレーション用の特定ハンドラ runtime = "nodejs22.x" timeout = 30 source_code_hash = data.archive_file.lambda_zip.output_base64sha256
tracing_config { mode = "Active" }
environment { variables = merge({ AWS_CONNECTION_REUSE_ENABLED = "1" }, var.env) }
tags = var.tags }
resource "aws_lambda_function" "get_documentation_handler" { filename = data.archive_file.lambda_zip.output_path function_name = "MyApi-GetDocumentation" role = aws_iam_role.lambda_execution_role.arn handler = "getDocumentation.handler" # このオペレーション用の特定ハンドラ runtime = "nodejs22.x" timeout = 30 source_code_hash = data.archive_file.lambda_zip.output_base64sha256
tracing_config { mode = "Active" }
environment { variables = merge({ AWS_CONNECTION_REUSE_ENABLED = "1" }, var.env) }
tags = var.tags }
# オペレーションごとに特定のリソースとメソッドを追加 resource "aws_api_gateway_resource" "say_hello_resource" { rest_api_id = module.rest_api.api_id parent_id = module.rest_api.api_root_resource_id path_part = "sayHello" }
resource "aws_api_gateway_method" "say_hello_method" { rest_api_id = module.rest_api.api_id resource_id = aws_api_gateway_resource.say_hello_resource.id http_method = "POST" authorization = "AWS_IAM" }
resource "aws_api_gateway_integration" "say_hello_integration" { rest_api_id = module.rest_api.api_id resource_id = aws_api_gateway_resource.say_hello_resource.id http_method = aws_api_gateway_method.say_hello_method.http_method
integration_http_method = "POST" type = "AWS_PROXY" uri = aws_lambda_function.say_hello_handler.invoke_arn }
resource "aws_api_gateway_resource" "get_documentation_resource" { rest_api_id = module.rest_api.api_id parent_id = module.rest_api.api_root_resource_id path_part = "documentation" }
resource "aws_api_gateway_method" "get_documentation_method" { rest_api_id = module.rest_api.api_id resource_id = aws_api_gateway_resource.get_documentation_resource.id http_method = "GET" authorization = "NONE" }
resource "aws_api_gateway_integration" "get_documentation_integration" { rest_api_id = module.rest_api.api_id resource_id = aws_api_gateway_resource.get_documentation_resource.id http_method = aws_api_gateway_method.get_documentation_method.http_method
integration_http_method = "GET" type = "HTTP" uri = "https://example.com/documentation" }
# デプロイメントの依存関係を更新~ resource "aws_api_gateway_deployment" "api_deployment" { rest_api_id = module.rest_api.api_id
depends_on = [ aws_api_gateway_integration.lambda_integration, aws_api_gateway_integration.say_hello_integration, aws_api_gateway_integration.get_documentation_integration, ]
lifecycle { create_before_destroy = true }
triggers = { redeployment = sha1(jsonencode([ aws_api_gateway_integration.say_hello_integration, aws_api_gateway_integration.get_documentation_integration, ])) } }
# 各関数にLambda権限を追加 resource "aws_lambda_permission" "say_hello_permission" { statement_id = "AllowExecutionFromAPIGateway-SayHello" action = "lambda:InvokeFunction" function_name = aws_lambda_function.say_hello_handler.function_name principal = "apigateway.amazonaws.com" source_arn = "${module.rest_api.api_execution_arn}/*/*" }
resource "aws_lambda_permission" "get_documentation_permission" { statement_id = "AllowExecutionFromAPIGateway-GetDocumentation" action = "lambda:InvokeFunction" function_name = aws_lambda_function.get_documentation_handler.function_name principal = "apigateway.amazonaws.com" source_arn = "${module.rest_api.api_execution_arn}/*/*" }
ルーターパターン
Section titled “ルーターパターン”すべてのAPIリクエストを処理する単一のLambda関数をデプロイしたい場合、APIのdefaultIntegrations
メソッドを編集して、統合ごとではなく単一の関数を作成できます:
export class MyApi<...> extends ... {
public static defaultIntegrations = (scope: Construct) => { const router = new Function(scope, 'RouterHandler', { ... }); return IntegrationBuilder.rest({ ... defaultIntegrationOptions: {}, buildDefaultIntegration: (op) => { return { // すべての統合で同じルータLambdaハンドラを参照 integration: new LambdaIntegration(router), }; }, }); };}
必要に応じて、router
関数をdefaultIntegrations
のパラメータとして定義するなど、他の方法でコードを修正することもできます。
Terraformモジュールはデフォルトでルーターパターンを使用します - これはデフォルトかつ唯一のサポートされるアプローチです。生成されたモジュールは、すべてのAPIオペレーションを処理する単一のLambda関数を作成します。
デフォルトモジュールをインスタンス化するだけでルーターパターンを取得できます:
# デフォルトのルーターパターン - 全オペレーション用単一Lambda関数module "my_api" { source = "../../common/terraform/src/app/apis/my-api"
# 単一Lambda関数が全オペレーションを自動処理 tags = local.common_tags}
アクセス権付与(IAM 認証時)
Section titled “アクセス権付与(IAM 認証時)”IAM 認証を選択した場合のアクセス権付与:
バンドルターゲット
Section titled “バンドルターゲット”ジェネレーターは自動的に 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 サーバー”ローカルサーバーの起動:
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
です。変更は自動的にリロードされます。
tRPC API の呼び出し
Section titled “tRPC API の呼び出し”型安全なクライアントを作成可能:
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 接続 ジェネレータの使用を検討してください。
詳細は tRPC 公式ドキュメント を参照してください。