Bỏ qua để đến nội dung

Smithy API đến Cơ sở dữ liệu quan hệ

Trình tạo connection kết nối một Smithy API với dự án Cơ sở dữ liệu quan hệ, tiêm một Prisma client vào ngữ cảnh dịch vụ để tất cả các triển khai hoạt động có thể truy cập cơ sở dữ liệu.

Trước khi sử dụng trình tạo này, hãy đảm bảo bạn có:

  1. Một dự án ts#smithy-api (backend TypeScript)
  2. Một dự án ts#rdb
  1. Cài đặt Nx Console VSCode Plugin nếu bạn chưa cài đặt
  2. Mở Nx Console trong VSCode
  3. Nhấp Generate (UI) trong phần "Common Nx Commands"
  4. Tìm kiếm @aws/nx-plugin - connection
  5. Điền các tham số bắt buộc
    • Nhấp Generate

    Chọn dự án backend Smithy API của bạn làm nguồn và dự án cơ sở dữ liệu quan hệ của bạn làm đích.

    Tham số Kiểu Mặc định Mô tả
    sourceProject Bắt buộc string - Dự án nguồn
    targetProject Bắt buộc string - Dự án đích để kết nối tới
    sourceComponent string - Component nguồn để kết nối từ đó (tên component, đường dẫn tương đối so với thư mục gốc của dự án nguồn, hoặc generator id). Sử dụng '.' để chọn rõ ràng dự án làm nguồn.
    targetComponent string - Component đích để kết nối tới (tên component, đường dẫn tương đối so với thư mục gốc của dự án đích, hoặc generator id). Sử dụng '.' để chọn rõ ràng dự án làm đích.

    Trình tạo sửa đổi ba tệp hiện có trong backend Smithy API của bạn:

    • Thư mụcpackages/api/src
      • context.ts Thuộc tính db được thêm vào ServiceContext
      • handler.ts Prisma client được tạo bên trong lambdaHandler, được truyền cho serviceHandler.handle
      • local-server.ts Prisma client được tạo bên trong request handler, được truyền cho serviceHandler.handle

    Ngoài ra, nó cập nhật target serve-local của API để tự động khởi động cơ sở dữ liệu.

    Trình tạo thêm một thuộc tính db có kiểu vào ServiceContext trong context.ts:

    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 client được khởi tạo bên trong lambdaHandler và được truyền qua ngữ cảnh dịch vụ:

    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);
    };

    Sử dụng cơ sở dữ liệu trong các hoạt động

    Phần tiêu đề “Sử dụng cơ sở dữ liệu trong các hoạt động”

    Truy cập db từ ngữ cảnh trong các triển khai hoạt động của bạn:

    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 };
    };

    Để cho phép API của bạn kết nối với cơ sở dữ liệu tại runtime, các hàm Lambda API phải được triển khai vào cùng VPC với cơ sở dữ liệu và được cấp quyền truy cập mạng và IAM.

    Trong application stack của bạn, triển khai API vào cùng VPC với cơ sở dữ liệu, sau đó gọi allowDefaultPortFromgrantConnect để mở đường dẫn mạng và cấp quyền IAM rds-db:connect cho mỗi Lambda handler:

    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);
    });

    Triển khai các hàm Lambda API vào private subnet with egress, không phải private isolated subnet. Tại runtime, getPrisma() truy xuất thông tin chi tiết kết nối cơ sở dữ liệu từ AWS AppConfig, đây là một public AWS service endpoint yêu cầu truy cập internet ra ngoài.

    Trình tạo áp dụng cùng một cách tiêm Prisma client bên trong request handler trong local-server.ts:

    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>

    Điều này khởi động cả API và cơ sở dữ liệu cục bộ. Biến môi trường SERVE_LOCAL=true được đặt tự động, vì vậy Prisma client kết nối với cơ sở dữ liệu Docker cục bộ thay vì Aurora.