RDSをデータソースとするGraphQL APIの構築

RDSをデータソースとするGraphQL APIの構築

AWS
Salesforce
AWS AppSync
AWS Lambda
Amazon EC2
GitHub Actions
Amazon RDS
Rollbar

概要

Amazon RDS上のMySQLのデータを外部から利用可能にするGraphQL APIを構築しました。

構成

Untitled.png

技術スタック

  • AWS CDK
    • AWSリソースはAWS CDK(TypeScript)を利用してIaC管理しました。
    • 開発者ごとに独立した環境を起動できるようにCDKレイヤーを実装しました。
    • 本番環境とそれ以外で一部の設定(RDSのマルチAZ, リソースの削除ポリシー, 独自ドメイン等)を調整できるようにしました。
  • GitHub Actions
    • CI/CDパイプラインの構築にGitHub Actionsを利用しました。
    • プルリクエスト作成時にESLint, Prettier, tscによる静的解析を実行するようにしました。
    • GraphQL Code Generatorの実行漏れもCIで確認するようにしました。
    • プルリクエスト作成時にJestによるユニットテストを実行するようにしました。
  • GraphQL Code Generator
    • GraphQLのリゾルバーを実装するAWS Lambdaで、各リゾルバーの型定義をGraphQLスキーマから自動生成するために利用しました。
  • GraphQL-Tools
    • AppSyncにデプロイするGraphQLスキーマを複数ファイルで見通し良く定義するために利用しました。
  • Jest
    • GraphQL APIのEnd-to-Endテストを構築しました。
    • Lambda関数にデプロイするTypeScriptコードのユニットテストを構築しました。
  • Prisma
    • RDBのORMとして利用しました。
  • Route 53 / Certificate Manager
    • AWS AppSyncに独自ドメインを設定しました。
  • Amazon EC2
    • GitHub ActionsからRDS上のMySQLに対してマイグレーションを実行するための実行環境として構築しました。
    • ローカル開発環境からE2Eテストを実行する際に直接RDBの内容を操作するための踏み台サーバーとしても利用しています。

特徴

サーバーレスなリソースであるAWS LambdaからRDSにアクセスする際はコネクション数に気をつける必要があります。ORMとして利用しているPrismaがPrepared Statementを利用するため、RDS Proxyを挟んでもピン留めが発生してしまい意味をなしません。今回の要件では、リクエスト数から見積もったLambdaの同時実行数が、利用したRDSのインスタンスタイプのコネクション数の上限未満であったため、Prismaのコネクションプール数を1にすることで特にコネクション数の対策を行わずに構築しました。

所感

データベースにRDBを利用したい場合で、PlanetScaleのようなサーバーレスRDBを利用せずRDSで構築する場合、必然的にVPCやプライベートサブネットを構築する必要が出てきて、結果としてVPC LambdaやVPC Endpoint、NAT Gatwayなどのリソースも必要となってくるので、工数もランニングコストも膨らみがちです。

また、開発環境を終了する際に、おそらくENIの削除の時間かと思われますが数十分かかってしまいます。

セキュリティ要件的に問題なければ、コネクションプーリングも行ってくれるPlanetScaleをMySQLサーバーとして、VPCを構築しないフルサーバーレス構成で構築するパターンが気に入っています。