Skip to content

Smithy API からリレーショナルデータベースへの接続

connection ジェネレーターは、Smithy APIリレーショナルデータベース プロジェクトに接続し、Prisma クライアントをサービスコンテキストに注入することで、すべての操作実装がデータベースにアクセスできるようにします。

このジェネレーターを使用する前に、以下を用意してください:

  1. ts#smithy-api プロジェクト(TypeScript バックエンド)
  2. ts#rdb プロジェクト
  1. インストール Nx Console VSCode Plugin まだインストールしていない場合
  2. VSCodeでNxコンソールを開く
  3. クリック Generate (UI) "Common Nx Commands"セクションで
  4. 検索 @aws/nx-plugin - connection
  5. 必須パラメータを入力
    • クリック Generate

    ソースとして Smithy API バックエンドプロジェクトを選択し、ターゲットとしてリレーショナルデータベースプロジェクトを選択します。

    パラメータ デフォルト 説明
    sourceProject 必須 string - ソース プロジェクト
    targetProject 必須 string - 接続先のターゲット プロジェクト
    sourceComponent string - 接続元のソース コンポーネント (コンポーネント名、ソース プロジェクト ルートからの相対パス、またはジェネレーター ID)。プロジェクトをソースとして明示的に選択するには '.' を使用します。
    targetComponent string - 接続先のターゲット コンポーネント (コンポーネント名、ターゲット プロジェクト ルートからの相対パス、またはジェネレーター ID)。プロジェクトをターゲットとして明示的に選択するには '.' を使用します。

    ジェネレーターは、Smithy API バックエンドの既存の3つのファイルを変更します:

    • Directorypackages/api/src
      • context.ts ServiceContextdb プロパティが追加されます
      • handler.ts lambdaHandler 内で Prisma クライアントが作成され、serviceHandler.handle に渡されます
      • local-server.ts リクエストハンドラー内で Prisma クライアントが作成され、serviceHandler.handle に渡されます

    さらに、API の serve-local ターゲットを更新して、データベースを自動的に起動するようにします。

    ジェネレーターは、context.tsServiceContext に型付きの db プロパティを追加します:

    packages/api/src/context.ts
    import { getPrisma as getMyDb } from ':my-scope/my-db';
    export interface ServiceContext {
    tracer: Tracer;
    logger: Logger;
    metrics: Metrics;
    myDb: Awaited<ReturnType<typeof getMyDb>>;
    }

    Prisma クライアントは lambdaHandler 内でインスタンス化され、サービスコンテキストを通じて渡されます:

    packages/api/src/handler.ts
    import { getPrisma as getMyDb } from ':my-scope/my-db';
    export const lambdaHandler = async (event: APIGatewayProxyEvent) => {
    const httpRequest = convertEvent(event);
    const myDb = await getMyDb();
    const httpResponse = await serviceHandler.handle(httpRequest, {
    tracer,
    logger,
    metrics,
    myDb,
    });
    return convertVersion1Response(httpResponse);
    };

    操作内でのデータベースの使用

    Section titled “操作内でのデータベースの使用”

    操作実装内で、コンテキストから db にアクセスします:

    packages/api/src/operations/list-users.ts
    import { ListUsersOperationInput, ListUsersOperationOutput } from '../generated/ssdk/index.js';
    import { ServiceContext } from '../context.js';
    export const listUsers = async (
    input: ListUsersOperationInput,
    ctx: ServiceContext,
    ): Promise<ListUsersOperationOutput> => {
    const users = await ctx.myDb.user.findMany();
    return { users };
    };

    実行時にAPIがデータベースに接続できるようにするには、API Lambda関数をデータベースと同じVPCにデプロイし、ネットワークおよびIAMアクセスを付与する必要があります。

    アプリケーションスタックで、APIをデータベースと同じVPCにデプロイし、allowDefaultPortFromgrantConnectを呼び出して、ネットワークパスを開き、各Lambdaハンドラーに IAM rds-db:connect権限を付与します:

    packages/infra/src/stacks/application-stack.ts
    import { MyDatabase } from ':my-scope/common-constructs';
    const db = new MyDatabase(this, 'Db', { vpc, ... });
    const api = new MyApi(this, 'Api', {
    integrations: MyApi.defaultIntegrations(this)
    .withDefaultOptions({
    vpc,
    vpcSubnets: { subnetType: SubnetType.PRIVATE_WITH_EGRESS },
    })
    .build(),
    });
    Object.entries(api.integrations).forEach(([operation, integration]) => {
    db.allowDefaultPortFrom(integration.handler, `Allow ${operation} to connect to the database`);
    db.grantConnect(integration.handler);
    });

    API Lambda関数は、プライベート分離サブネットではなく、エグレス付きプライベートサブネットにデプロイしてください。実行時に、getPrisma()はAWS AppConfigからデータベース接続の詳細を取得しますが、これはアウトバウンドインターネットアクセスを必要とするパブリックAWSサービスエンドポイントです。

    ジェネレーターは、local-server.ts のリクエストハンドラー内でも同じ Prisma クライアントの注入を適用します:

    packages/api/src/local-server.ts
    import { getPrisma as getMyDb } from ':my-scope/my-db';
    const server = createServer(async function (req, res) {
    const httpRequest = convertRequest(req);
    const myDb = await getMyDb();
    const httpResponse = await serviceHandler.handle(httpRequest, {
    tracer,
    logger,
    metrics,
    myDb,
    });
    return writeResponse(httpResponse, res);
    });
    Terminal window
    pnpm nx serve-local <api-project-name>

    これにより、API とローカルデータベースの両方が起動します。SERVE_LOCAL=true 環境変数が自動的に設定されるため、Prisma クライアントは Aurora ではなくローカルの Docker データベースに接続します。