AWS Amplifyの現在地 - SSR対応とGen 2で変わった開発体験、そして変わらない制約
Amplifyの大きな進化 - 過去の制約がどう変わったか
AWS Amplifyを2年前に触った方が今改めて見ると、その進化に驚くはずです。特に大きな変化は「SSR対応」と「拡張性の向上」です。これまでSPAに限定されていたAmplifyが、SEO要件のあるtoCプロダクトでも選択肢に入るようになりました。
SSRの完全サポート - もはやSPA専用ではない
Amplify HostingがNext.js 12から15までのSSRをネイティブサポートしたことで、状況は一変しました。SSG(Static Site Generation)、ISR(Incremental Static Regeneration)、API Routes、App RouterとPages Router両方に対応し、モダンなNext.jsアプリケーションの要件をほぼカバーしています。
さらに注目すべきは、NuxtやAstro、SvelteKitもビルドアダプター経由で対応している点です。Next.js以外のフレームワークを採用している組織でも、Amplifyのマネージドホスティングの恩恵を受けられるようになりました。
Amplify JS v6では、Next.jsのサーバーランタイムでAuthやDataを扱うためのSSRガイドも整備されています。認証状態の管理やサーバーサイドでのデータフェッチなど、実装で悩みがちな部分に対する公式のベストプラクティスが提供されるようになりました。
既存リソースとの連携 - ゼロベースでなくても始められる
「既存DBの使い回しは不可能に近い」という過去の制約も、現在では大きく改善されています。
@sql
ディレクティブによる既存MySQL/PostgreSQLデータベースとの接続が可能になりました。これにより、既存のRDBを持つ組織でも、GraphQL APIを段階的に導入できるようになっています。
type Post @model @sql(statement: "SELECT * FROM posts WHERE id = :id") {
id: ID!
title: String!
content: String!
author: String!
}
また、既存のDynamoDBテーブルやS3バケットのインポートもサポートされています。amplify import storage
コマンドで既存リソースをAmplifyの管理下に取り込めるため、段階的な移行戦略が立てられます。
拡張性の劇的な向上 - Gen 2とCDK統合
Amplify Gen 2の最大の特徴は「TypeScript/Code-first」アプローチと「CDK統合」です。
リゾルバーの上書きやカスタム追加が公式手順として提供され、VTLやJavaScriptでのカスタムロジック実装が可能になりました。自動生成されたリゾルバーでは対応できない複雑なビジネスロジックも、適切にオーバーライドできます。
さらに重要なのは、CDKによるカスタムリソースの追加や既存リソースのオーバーライドが第一級のサポートとなった点です。VPCの設定、ElastiCacheの追加、カスタムLambdaレイヤーの作成など、Amplifyがネイティブサポートしていない機能も自由に追加できます。
import * as cdk from 'aws-cdk-lib';
import * as elasticache from 'aws-cdk-lib/aws-elasticache';
import { defineBackend } from '@aws-amplify/backend';
const backend = defineBackend({
// Amplifyリソース定義
});
const stack = backend.createStack('custom-stack');
// ElastiCacheクラスタを追加
new elasticache.CfnCacheCluster(stack, 'RedisCluster', {
cacheNodeType: 'cache.t3.micro',
engine: 'redis',
numCacheNodes: 1,
});
検索とデータモデリング - OpenSearchへの移行と新しいディレクティブ
ElasticsearchからOpenSearchへ
過去の記事で言及されていた「Elasticsearch」は、現在Amazon OpenSearch Serviceに置き換わっています。@searchable
ディレクティブは、複合ソート、フィルタ、ページングに加えて「総件数(total)」の取得もサポートするようになりました。
既存データに後付けで@searchable
を有効化する場合のバックフィル手順も公式化されています。DynamoDBからOpenSearchへのデータ移行スクリプトと具体的なパラメータが提示され、本番環境での移行作業も安全に実施できるようになりました。
Transformer v2による新しいインデックス定義
Transformer v2では@key
ディレクティブが@primaryKey
と@index
に分離されました。これにより、プライマリキーとGSI(グローバルセカンダリインデックス)の定義がより明確になっています。
# 旧(Transformer v1)
type Post @model @key(fields: ["type", "createdAt"]) {
id: ID!
type: String!
createdAt: AWSDateTime!
}
# 新(Transformer v2)
type Post @model {
id: ID! @primaryKey
type: String! @index(name: "byTypeAndDate", sortKeyFields: ["createdAt"])
createdAt: AWSDateTime!
}
GSIの後付け変更も可能になりましたが、複数のGSI変更をまとめて適用する際は「iterative GSI updates」のフラグ有効化が推奨されています。複合ソートキーを新設した場合は、合成キーのバックフィルが必要になる点は注意が必要です。
依然として残る制約と実務上の考慮点
DynamoDBバックエンドの根本的な制限
Amplifyが大きく進化した一方で、DynamoDBをバックエンドとするGraphQL APIのページネーションには依然として制約があります。
DynamoDB直結のlist系クエリにおける制約は以下の通りです。
- nextTokenによる連結型ページングのみ(任意ページ番号からの開始は不可)
- 総件数の返却なし(全件スキャンが必要なため)
- ソートはインデックスのソートキーに限定(任意フィールドの多段ソートは不可)
これらの制約はDynamoDBのQuery操作の仕様に起因するため、Amplifyの進化では解決できない部分です。
ページネーションUIの設計制約
「全100件中、41-60件を表示」といった一般的なページネーションUIは、DynamoDBバックエンドでは実装が困難です。nextTokenベースのページングでは、現在のページ番号や総ページ数を計算できないためです。
実務では以下のような対応が必要になります。
- 「次へ」「前へ」のみのシンプルなナビゲーション採用
- OpenSearch連携による総件数取得とページング実装
- 別途カウント用のテーブルやキャッシュレイヤーの実装
リージョン制約とサービス可用性
@sql
によるRDB連携は、まだ全リージョンで利用可能ではありません。東京リージョンでは利用可能ですが、採用前に対象リージョンのサポート状況を確認する必要があります。
現在のAmplify採用判断フレームワーク
積極的に採用を検討すべきケース
現在のAmplifyは、以下のようなプロジェクトで特に威力を発揮します。
スタートアップの新規事業立ち上げフェーズにおける採用価値は以前より高まっています。
- MVP(Minimum Viable Product)の高速開発が求められる
- SEO要件があるtoCサービスでもSSR対応により選択可能
- 既存のRDBやDynamoDBを活用した段階的な移行が可能
- CDK統合により、成長に応じた機能拡張の道筋が見える
エンタープライズでの部分的な採用も現実的になりました。
- 社内向け管理画面やダッシュボード構築
- 既存システムとGraphQL APIで連携する新規サービス
- プロトタイピングから本番移行までの連続的な開発
慎重に検討すべきケース
一方で、以下のような要件がある場合は、制約を理解した上での採用判断が必要です。
複雑な検索・集計要件がコア機能の場合は要注意です。
- 多様な条件での複合検索とソート
- リアルタイムな集計処理
- 柔軟なページネーションUI(ページ番号指定など)
大規模トランザクション処理には向いていません。
- 複数テーブルにまたがる整合性保証
- 複雑なビジネスロジックを含むバッチ処理
- 既存の複雑なストアドプロシージャの移植
実装前のチェックリスト(2025年版)
Amplify採用を検討する際の確認事項を整理しました。
アーキテクチャ要件の確認
プロジェクトの技術要件を以下の観点で整理します。
- フロントエンド要件
- SSR/SSG/ISRの必要性(Next.js 12-15での実装を想定)
- 使用予定のフレームワーク(Next.js以外の場合はアダプター対応を確認)
- SEOの重要度とCore Web Vitalsの目標値
- データモデルとアクセスパターン
- 主要なエンティティとその関係性
- 読み書きの頻度とパターン
- インデックス設計(GSI上限20個の制約内で実現可能か)
- 検索・ページネーション要件
- 検索条件の複雑さ(AND/OR、部分一致、範囲検索など)
- ソート要件(単一/複合、動的な切り替え)
- ページネーションUI(nextTokenで実現可能か、総件数表示は必須か)
移行・拡張性の確認
将来的な成長や変更に対する柔軟性を確認します。
- 既存資産の活用
- 既存DBの有無と移行戦略
- 既存のAWSリソース(S3、DynamoDB等)の活用可否
- 認証基盤との連携要件
- カスタマイズ要件
- Amplifyでサポートされない機能の洗い出し
- CDKでの拡張で対応可能な範囲の確認
- カスタムリゾルバーの必要性
- 非機能要件
- パフォーマンス目標(レスポンスタイム、同時接続数)
- 可用性要件(マルチリージョン対応など)
- セキュリティ要件(VPC接続、暗号化要件など)
実装における具体的な対処法
OpenSearchを活用した高度な検索実装
DynamoDBの検索制約を回避するため、OpenSearchとの併用パターンを紹介します。
type Product @model @searchable {
id: ID!
name: String!
description: String
price: Float!
category: String! @index(name: "byCategory")
tags: [String]
createdAt: AWSDateTime!
}
上記のように@searchable
を追加することで、OpenSearchでの全文検索が可能になります。検索クエリでは総件数の取得も可能です。
query SearchProducts {
searchProducts(
filter: {
name: { match: "キーワード" }
price: { range: [1000, 5000] }
}
sort: [
{ field: price, direction: desc }
{ field: createdAt, direction: asc }
]
limit: 20
) {
items {
id
name
price
}
total # 総件数が取得可能
nextToken
}
}
CDKによる機能拡張の実装例
Amplifyがネイティブサポートしていない機能をCDKで追加する例を示します。
import { defineBackend } from '@aws-amplify/backend';
import { Stack } from 'aws-cdk-lib';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as rds from 'aws-cdk-lib/aws-rds';
const backend = defineBackend({
auth,
data,
});
// カスタムスタックの作成
const customStack = backend.createStack('custom-resources');
// VPCの作成
const vpc = new ec2.Vpc(customStack, 'CustomVPC', {
maxAzs: 2,
natGateways: 1,
});
// RDS Auroraクラスターの追加
const cluster = new rds.DatabaseCluster(customStack, 'AuroraCluster', {
engine: rds.DatabaseClusterEngine.auroraPostgres({
version: rds.AuroraPostgresEngineVersion.VER_15_4,
}),
vpc,
defaultDatabaseName: 'myapp',
});
// Lambda関数にVPCとRDS接続情報を渡す
backend.data.resources.cfnResources.cfnGraphqlApi.addEnvironment('DATABASE_URL', cluster.clusterEndpoint.socketAddress);
バックフィル戦略の実装
既存データに@searchable
を後付けする際のバックフィル実装例です。
const AWS = require('aws-sdk');
const { Client } = require('@opensearch-project/opensearch');
const dynamodb = new AWS.DynamoDB.DocumentClient();
const openSearchClient = new Client({
node: process.env.OPENSEARCH_ENDPOINT,
});
async function backfillToOpenSearch(tableName, indexName) {
let lastEvaluatedKey = null;
let processedCount = 0;
do {
const params = {
TableName: tableName,
Limit: 100,
ExclusiveStartKey: lastEvaluatedKey,
};
const result = await dynamodb.scan(params).promise();
// バルクインサート用のデータ準備
const bulkBody = result.Items.flatMap(item => [
{ index: { _index: indexName, _id: item.id } },
item
]);
// OpenSearchへのバルクインサート
await openSearchClient.bulk({ body: bulkBody });
processedCount += result.Items.length;
console.log(`Processed ${processedCount} items`);
lastEvaluatedKey = result.LastEvaluatedKey;
} while (lastEvaluatedKey);
console.log(`Backfill completed. Total items: ${processedCount}`);
}
成功事例に見る採用パターン
パターン1:段階的な移行戦略
ある金融系スタートアップでは、既存のPostgreSQLデータベースを維持しながら、新機能をAmplifyで開発する戦略を採用しました。
既存システムとの連携における実装アプローチを以下に示します。
- 既存DBは
@sql
ディレクティブで読み取り専用として接続 - 新規データはDynamoDBに保存し、GraphQL APIで管理
- 段階的にデータを移行し、最終的に完全なAmplify化を実現
パターン2:マイクロサービス的な部分採用
大手ECサイトでは、レコメンデーション機能のみをAmplifyで実装する例があります。
部分的な採用における利点は以下の通りです。
- メインシステムから独立した開発・デプロイが可能
- GraphQL APIによる柔軟なデータ取得
- CDKでメインシステムとの連携部分をカスタマイズ
表 Amplify採用パターンと適用領域
採用パターン | 適用領域 | 主な利点 | 注意点 |
---|---|---|---|
フルAmplify | 新規サービス全体 | 開発速度最大化、統一された開発体験 | 制約への完全な適合が必要 |
段階的移行 | 既存システムの modernization | リスク最小化、既存資産の活用 | 移行期間中の複雑性 |
部分採用 | 特定機能のマイクロサービス化 | 独立性、技術的な実験 | システム間連携の設計 |
プロトタイプ→本番 | MVP開発から本番への連続的な成長 | 初速の最大化、フィードバック反映の速さ | スケール時の再設計可能性 |
今後の展望と準備すべきこと
Amplify Gen 3への期待
現在のGen 2でも大幅な改善が見られますが、コミュニティからは更なる要望が上がっています。
今後期待される機能強化は以下の通りです。
- DynamoDB Streamsのネイティブサポート強化
- Step Functionsとの統合
- コンテナベースのカスタムランタイムサポート
組織としての準備
Amplifyを効果的に活用するために、組織として準備すべき事項があります。
開発チームのスキルセット見直しが重要です。
フロントエンドエンジニアにも、DynamoDBやGraphQLの基礎知識が求められるようになります。逆に、インフラエンジニアの作業は大幅に削減され、より戦略的な設計に注力できるようになります。
ガバナンスとコスト管理の仕組み作りも必須です。
開発の民主化が進む一方で、無秩序なリソース作成を防ぐためのガバナンスが必要です。AWS Organizationsと連携したコスト管理、IAMポリシーによる適切な権限管理など、事前の設計が重要になります。
まとめ - Amplifyは「制約のあるフレームワーク」から「戦略的な選択肢」へ
2025年現在のAmplifyは、かつての「制約だらけのフレームワーク」から「戦略的に選択可能なプラットフォーム」へと進化しています。SSR対応により適用範囲が広がり、CDK統合により拡張性が確保され、既存リソースとの連携も可能になりました。
一方で、DynamoDBのアーキテクチャに起因する制約は依然として存在し、すべてのユースケースに適合するわけではありません。重要なのは、これらの制約を理解した上で、プロジェクトの特性に応じた適切な判断を下すことです。
特にスタートアップや新規事業において、「スピード」と「将来の拡張性」のバランスを取りたい場合、現在のAmplifyは非常に魅力的な選択肢となります。初期はAmplifyの恩恵を最大限に活用し、成長に応じてCDKで機能を拡張し、必要に応じて部分的なマイグレーションを行う、という戦略的なアプローチが可能になったためです。
Amplifyの採用を検討する際は、単に「使える/使えない」の二元論ではなく、「どのフェーズでどう活用するか」という観点で評価することをお勧めします。技術選定は、プロダクトのライフサイクル全体を見据えた戦略的な意思決定であるべきです。