- 1 なぜ Application Integration Vol1 か — メッセージング5層アーキテクチャ概観
- 2 Amazon SQS 本番運用 — Standard vs FIFO / DLQ設計 / Visibility Timeout / Lambda統合
- 3 Amazon SNS 本番運用 — Fan-out / サブスクリプションフィルタ / FIFO Topic
- 4 Amazon EventBridge 本番運用 — イベントバス / Scheduler / Pipes / Schema Registry
- 5 Amazon API Gateway 本番運用 — REST vs HTTP API / 認可統合 / スロットリング
- 6 AWS AppSync 本番運用 — GraphQLスキーマ / リゾルバ / リアルタイムサブスクリプション
- 7 詰まりポイント7選 + アンチパターン→正解パターン変換
- 7.1 詰まり1 — SQS Visibility Timeout 不足で同一メッセージ二重処理
- 7.2 詰まり2 — SNS サブスクリプションフィルタ誤設定でメッセージ消失
- 7.3 詰まり3 — EventBridge イベントパターン不一致で静かに捨てられる
- 7.4 詰まり4 — API Gateway スロットリング未設定でバースト時429/502
- 7.5 詰まり5 — AppSync Resolver VTL構文エラーでGraphQL null応答
- 7.6 詰まり6 — SQS FIFO MessageGroupId設計ミスで全キュー直列化
- 7.7 詰まり7 — EventBridge Archive未設定でイベント再生不能
- 7.8 アンチパターン→正解パターン変換 演習5問
- 8 まとめ — Application Integration Vol1 起点宣言 + 全軸クロスリンク
なぜ Application Integration Vol1 か — メッセージング5層アーキテクチャ概観
Vol1(統合プラットフォーム基盤・本記事) — つなぐ・流す・制御する
| 章 | テーマ | 主な施策 |
|—-|——–|———|
| §2 | Amazon SQS 本番運用 | Standard/FIFO選定・DLQ設計・Lambda統合 |
| §3 | Amazon SNS 本番運用 | Fan-out・サブスクリプションフィルタ・FIFO Topic |
| §4 | Amazon EventBridge 本番運用 | イベントバス設計・Scheduler・Pipes・Schema Registry |
| §5 | Amazon API Gateway 本番運用 | REST/HTTP API選定・認可統合・スロットリング |
| §6 | AWS AppSync 本番運用 | GraphQLスキーマ・リゾルバ・リアルタイムサブスクリプション |
| §7 | 詰まりポイント7選 + 演習 | 頻出パターンの解決策 + アンチパターン変換5問 |

全24軸のAWSハンズオンシリーズを通じて、Computing(EC2/ECS/EKS)・Storage(S3/EFS)・Database(RDS/DynamoDB)・Serverless(Lambda/Step Functions)・Observability(CloudWatch/X-Ray)など主要サービス群を体系的に習得してきた。しかし現場での設計力を問われるとき、最も差が出るのは「個々のサービスを使いこなす力」より「サービス間をどう繋ぐか」だ。
マイクロサービスが当たり前になった今、1つのリクエストが複数のサービスを跨ぐのは標準だ。その接合部——Application Integration——を設計する力こそが、Cloud Architectとして一段上に行くために必要なスキルになる。
メッセージング5層アーキテクチャ
AWSのApplication Integrationサービスは、役割と抽象度で5層に整理できる。
| レイヤー | サービス | 役割 | 代表ユースケース |
|---|---|---|---|
| Queue | Amazon SQS | 非同期メッセージキューイング・デカップリング | ワーカーバッファリング / 非同期処理 |
| Pub-Sub | Amazon SNS | トピックへの発行→複数サブスクライバへFan-out | 障害通知 / 複数Lambda同時起動 |
| Event Bus | Amazon EventBridge | イベント駆動ルーティング / スケジューリング / SaaS統合 | サービス間疎結合 / 定時バッチ |
| API Management | Amazon API Gateway | REST/HTTP APIの公開・保護・管理 | モバイル/Web向けAPIエンドポイント |
| GraphQL | AWS AppSync | スキーマ駆動GraphQL / リアルタイムサブスクリプション | フロントエンド統合 / リアルタイム更新 |
5つは競合するサービスではなく、相補的に組み合わせて使う統合レイヤーだ。本番環境での典型的な組み合わせを見てみよう。
API Gateway → SQS → Lambda(非同期処理) → SNS(結果通知) → EventBridge(監査ログ転送)
この1本のフローの中に5サービスのうち4つが登場する。それぞれが独立した役割を持ちながら、疎結合に連携する——これがApplication Integrationの本質だ。
Serverless Vol2との差別化
Serverless Vol2では、Lambda中心のEvent-Driven Architectureを軸に、SQS/SNS/EventBridgeをイベント駆動の「脇役」として解説した。SQS選定マトリクス・SNS Fan-out基礎・EventBridgeイベントバス基本が中心で、API GatewayとAppSyncは対象外だった。
本記事はその逆アプローチをとる。統合プラットフォーム視点でSQS/SNS/EventBridge/API Gateway/AppSyncを「主役」として個別深堀りする。
- SQS: Standard vs FIFO 5軸選定、DLQ設計(maxReceiveCount根拠・redrive戦略)、Visibility Timeout最適設計、部分バッチ応答
- SNS: FIFO Topicの活用、サブスクリプションフィルタ設計、モバイルプッシュ、クロスアカウント配信
- EventBridge: Scheduler(分散Cronの置き換え)、Pipes(サービス間ブリッジ)、Schema Registry(スキーマ管理)
- API Gateway: REST vs HTTP API選定基準、Cognito/Lambda認可統合、スロットリング・キャッシュ設計
- AppSync: GraphQLスキーマ設計、リゾルバパイプライン、WebSocketサブスクリプション、Merged API
本記事で獲得できる設計力
本記事を通読することで、以下の設計判断が単独でできるようになる。
- SQS: Standard/FIFO選定・DLQ maxReceiveCount設計・Visibility Timeout最適値・Lambda Event Source Mapping部分バッチ応答
- SNS: Fan-outパターン・サブスクリプションフィルタ設計・FIFO Topicの用途・クロスアカウント配信
- EventBridge: カスタムイベントバス設計・Schedulerによる定時実行・Pipesによるサービス間ブリッジ・Schema Registryによるスキーマ管理
- API Gateway: REST vs HTTP API選定・Cognito/Lambda認可統合・スロットリング設定・キャッシュ戦略
- AppSync: GraphQLスキーマ設計・リゾルバパイプライン・WebSocketサブスクリプション・Merged API構成
さらに§7の「詰まりポイント7選」とアンチパターン演習5問で、実際の設計現場で直面しやすいミスパターンとその解決策を体験する。Application Integration Seriesのvol1として、第25軸目の起点にふさわしい内容に仕上げた。
Amazon SQS 本番運用 — Standard vs FIFO / DLQ設計 / Visibility Timeout / Lambda統合

SQSはAWS最古のサービスの一つであり、最も実績のある非同期メッセージキューイングサービスだ。表面上はシンプルに見えるが、本番運用で使いこなすには複数の設計判断が求められる。
Standard vs FIFO — 選定5軸比較
SQSを使う最初の判断は「Standard か FIFO か」だ。5軸で比較する。
| 選定軸 | Standard Queue | FIFO Queue |
|---|---|---|
| 順序保証 | ベストエフォート(順序不保証) | 厳密な順序保証(送信順) |
| 重複配信 | At-Least-Once(重複あり) | Exactly-Once(5分間ウィンドウ内) |
| スループット | 無制限(virtually unlimited) | 最大3,000 msg/s(バッチ) / 300 msg/s(単体) |
| コスト | 基準価格 | Standard比約10%高 |
| 主なユースケース | 画像変換 / メール送信 / ログ収集 | 金融取引 / 注文処理 / 在庫管理 |
選定の原則:
- 「順序が壊れたら業務が壊れる」→ FIFO一択
- 「スループット10,000 msg/s超が必要」→ Standard一択
- 「重複処理はアプリ側で冪等性を持って対処できる」→ Standard(コスト効率優先)
DLQ(Dead Letter Queue)設計
DLQはSQS本番運用の要だ。処理失敗メッセージを隔離し、本キューを健全に保つ。
maxReceiveCount設計(失敗許容回数)
Lambdaの処理失敗カウントが maxReceiveCount を超えると、メッセージはDLQへ転送される。
{
"deadLetterTargetArn": "arn:aws:sqs:ap-northeast-1:123456789012:MyQueue-DLQ",
"maxReceiveCount": 3
}
推奨値は 3〜5回 だ。根拠を整理する。
- 1〜2回: 一時的ネットワーク障害で即DLQ転送 → 誤検知が多い
- 3〜5回: 一時障害を吸収しつつ、無限ループを早期遮断
- 10回以上: DLQ転送が遅れ、本キューのメッセージ滞留が長引く
LambdaのEvent Source Mappingのリトライ設定(maxRetryAttempts 最大2回)と合わせて設計することが重要だ。bisectOnFunctionError=true と組み合わせると、バッチのどのメッセージが失敗したかを特定できる。
DLQ Redrive(再処理)
DLQ内のメッセージは修正後に本キューへ再投入(Redrive)できる。
import boto3
sqs = boto3.client('sqs')
response = sqs.start_message_move_task(
SourceArn='arn:aws:sqs:ap-northeast-1:123456789012:MyQueue-DLQ',
DestinationArn='arn:aws:sqs:ap-northeast-1:123456789012:MyQueue',
MaxNumberOfMessagesPerSecond=10
)
task_handle = response['TaskHandle']
StartMessageMoveTask は非同期で実行される。最大10 msg/sのレートで制御でき、本番キューへの急激な流入を防ぐ。
DLQアラーム設定
DLQにメッセージが1件でも入ったら即座にアラームを上げるべきだ。
{
"AlarmName": "SQS-DLQ-MessageVisible",
"MetricName": "ApproximateNumberOfMessagesVisible",
"Namespace": "AWS/SQS",
"Statistic": "Sum",
"Period": 60,
"EvaluationPeriods": 1,
"Threshold": 0,
"ComparisonOperator": "GreaterThanThreshold",
"Dimensions": [{"Name": "QueueName", "Value": "MyQueue-DLQ"}]
}
DLQを設定しないと何が起きるか? maxReceiveCountを超えたメッセージはデフォルトでキュー内に残り続ける。VisibilityTimeout期間を経て再度配信され、また失敗し——という無限ループが発生する。結果として正常メッセージの処理が遅延し、Lambda同時実行数を食い潰すリスクがある。SQSキューには必ずDLQをペアで設定すること。
Visibility Timeout 設計
Visibility Timeoutは「メッセージを受信してから他のコンシューマに見えなくなる時間」だ。コンシューマ(Lambda/EC2)が処理完了前にこの時間を超えると、同じメッセージが再配信される。
デフォルト値と設計指針:
| パラメータ | 値 |
|---|---|
| デフォルト | 30秒 |
| 最小 | 0秒 |
| 最大 | 12時間 |
Lambda統合時の推奨値
Visibility Timeout = Lambda Timeout × 6
Lambda Timeoutが30秒なら Visibility Timeout は180秒(3分)に設定する。「×6」の根拠はLambdaの再試行ポリシーを考慮した余裕係数だ。Lambdaがタイムアウトした場合でもメッセージが再配信可能になるまでの時間を十分確保できる。
ChangeMessageVisibility による動的延長
処理が予想より長引いた場合、削除前に Visibility Timeout を延長できる。
import boto3
sqs = boto3.client('sqs')
def extend_visibility(queue_url: str, receipt_handle: str, new_timeout: int = 300):
sqs.change_message_visibility(
QueueUrl=queue_url,
ReceiptHandle=receipt_handle,
VisibilityTimeout=new_timeout
)
長時間処理(機械学習推論・大容量ファイル変換等)では、処理ループ内で定期的に延長するパターンが有効だ。最大延長時間は初回受信から12時間以内。
Long Polling vs Short Polling
SQSのポーリングには2種類ある。
| 方式 | ReceiveMessageWaitTimeSeconds | 動作 | コスト傾向 |
|---|---|---|---|
| Short Polling | 0(デフォルト) | メッセージがなくてもすぐ返す | APIコール数が多くなりやすい |
| Long Polling | 1〜20秒 | メッセージが来るか指定秒数待つ | APIコール数を削減 |
aws sqs set-queue-attributes \
--queue-url https://sqs.ap-northeast-1.amazonaws.com/123456789012/MyQueue \
--attributes ReceiveMessageWaitTimeSeconds=20
Long Pollingを選ぶべき理由:
- 空レスポンスが減り、APIコストが約10〜20%削減できる
- ポーリング間隔が短くなるためレイテンシも低減(メッセージ到着を即検知)
- 特別な理由がなければ
ReceiveMessageWaitTimeSeconds=20に設定する
バッチ処理 — SendMessageBatch / DeleteMessageBatch
SQSのAPIコストはリクエスト数課金だ。バッチAPIを使うとコストを最大10分の1に削減できる。
import boto3
sqs = boto3.client('sqs')
entries = [
{'Id': str(i), 'MessageBody': f'message-{i}'}
for i in range(10)
]
response = sqs.send_message_batch(
QueueUrl='https://sqs.ap-northeast-1.amazonaws.com/123456789012/MyQueue',
Entries=entries
)
if response.get('Failed'):
for failure in response['Failed']:
print(f"Failed: {failure['Id']} - {failure['Message']}")
削除もバッチで行う。Lambda Event Source Mappingでは自動バッチ削除されるが、EC2/ECSコンシューマでは明示的な削除が必要だ。
def delete_batch(queue_url: str, receipts: list):
entries = [
{'Id': str(i), 'ReceiptHandle': rh}
for i, rh in enumerate(receipts)
]
sqs.delete_message_batch(QueueUrl=queue_url, Entries=entries)
バッチサイズは最大10件。256 KB以下の制約はバッチ全体に適用される(1メッセージあたりの制限ではない)。
Lambda SQS Event Source Mapping
LambdaとSQSの統合はEvent Source Mapping(ESM)を通じて行う。ポーリングとバッチ処理をLambdaが代行するため、コンシューマコードが大幅に簡略化される。
主要パラメータ:
| パラメータ | 説明 | 推奨設定 |
|---|---|---|
batchSize | 1回のLambda呼び出しに含めるメッセージ数 | Standard: 10〜1000 / FIFO: 10 |
maximumBatchingWindowInSeconds | バッチを積み上げる最大待機時間 | 0〜300秒(コスト最適化時は30〜60秒) |
functionResponseTypes | 部分バッチ応答を有効化 | ["ReportBatchItemFailures"] |
bisectOnFunctionError | バッチ失敗時に二分割して再試行 | true(デバッグ効率化) |
部分バッチ応答(ReportBatchItemFailures)
バッチ内の一部メッセージが失敗した際、失敗したメッセージだけをDLQに送り、成功したものは正常処理できる。
def handler(event, context):
batch_item_failures = []
for record in event['Records']:
try:
process_message(record['body'])
except Exception as e:
batch_item_failures.append({
'itemIdentifier': record['messageId']
})
return {'batchItemFailures': batch_item_failures}
ReportBatchItemFailures を有効化しない場合、バッチ内の1件失敗でバッチ全体が再試行される。成功済みメッセージの重複処理リスクがあるため、必ず有効化すること。
{
"EventSourceArn": "arn:aws:sqs:ap-northeast-1:123456789012:MyQueue",
"BatchSize": 100,
"MaximumBatchingWindowInSeconds": 30,
"FunctionResponseTypes": ["ReportBatchItemFailures"],
"BisectBatchOnFunctionError": true
}
– BatchSize=100 + BatchingWindow=30s でスループット向上とコスト削減を両立
– ReportBatchItemFailures で部分失敗に対応し、成功済みメッセージの重複処理を防ぐ
– BisectBatchOnFunctionError=true で障害切り分けを高速化
FIFO キュー — MessageGroupId 設計
FIFOキューの順序保証は MessageGroupId 単位 で行われる。同一MessageGroupId内のメッセージのみ順序保証・重複排除が適用される。
メッセージ送信例:
import boto3
sqs = boto3.client('sqs')
sqs.send_message(
QueueUrl='https://sqs.ap-northeast-1.amazonaws.com/123456789012/MyQueue.fifo',
MessageBody='order-data',
MessageGroupId='order-123',
MessageDeduplicationId='order-123-2026-01-01T10:00:00Z'
)
MessageGroupId設計パターン:
| 設計方針 | 効果 | トレードオフ |
|---|---|---|
| 全メッセージ同一(例: “default”) | 全順序保証 | 並列処理不可(1スレッドのみ) |
| エンティティID(例: “order-123″) | エンティティ内順序保証 | 同一エンティティは順次処理 |
| 細粒度(ランダムUUID等) | 並列処理最大化 | 順序保証なし(Standardと同等) |
推奨: 「どの粒度で順序を保証したいか」を業務要件から逆算してGroupIdを設計する。金融取引なら口座ID、注文処理なら注文ID、在庫管理なら商品IDが典型的な設計だ。
MessageDeduplicationId は重複排除に使用する。同一DeduplicationIdが5分以内に再送された場合、2回目以降は無視される。ContentBasedDeduplication(メッセージ内容のSHA-256)を有効化すれば明示指定が不要になるが、本当に同一内容のメッセージが異なるタイミングで正当に送信される場合は必ず明示的に一意のIDを指定すること。
Amazon SNS 本番運用 — Fan-out / サブスクリプションフィルタ / FIFO Topic
sequenceDiagram
participant Publisher
participant SNS as SNS Topic
participant SQS as SQS Queue
participant Lambda as Lambda Function
participant HTTP as HTTP Endpoint
Publisher->>SNS: Publish Message
SNS-->>SQS: Fan-out (Queue処理)
SNS-->>Lambda: Fan-out (即時処理)
SNS-->>HTTP: Fan-out (外部通知)
Note over SNS: サブスクリプションフィルタで<br/>配信先を選択的に制御
トピック設計: Standard Topic vs FIFO Topic
SNSトピックは用途に応じてStandardとFIFOを選択する。
| 比較項目 | Standard Topic | FIFO Topic |
|---|---|---|
| スループット | 無制限 (ソフトリミット 30,000 msg/秒) | 300 msg/秒 (バッチ3,000 msg/秒) |
| 配信保証 | At-least-once (重複あり) | Exactly-once (MessageDeduplicationId) |
| 順序保証 | なし | MessageGroupId単位で保証 |
| サブスクライバー | SQS/Lambda/HTTP/Email/SMS/Mobile Push | SQS FIFO Queueのみ |
FIFO Topicはサブスクライバーが SQS FIFO Queue のみ に制限される点に注意。LambdaやHTTPエンドポイントを直接サブスクライブすることはできない。
import boto3
import json
sns = boto3.client('sns', region_name='ap-northeast-1')
# FIFO Topic作成 (.fifo サフィックス必須)
response = sns.create_topic(
Name='OrderProcessing.fifo',
Attributes={
'FifoTopic': 'true',
'ContentBasedDeduplication': 'false' # MessageDeduplicationIdを明示指定する場合はfalse
}
)
topic_arn = response['TopicArn']
# FIFO Topicへのメッセージ送信
sns.publish(
TopicArn=topic_arn,
Message='{"orderId": "ORD-12345", "amount": 5000}',
MessageGroupId='customer-group-A',# 同グループ内の順序保証
MessageDeduplicationId='order-ORD-12345-v1'# 5分間の重複排除ウィンドウ
)
サブスクリプションフィルタポリシー
フィルタポリシーで特定のサブスクライバーにだけメッセージを配信する。フィルタスコープは2種類ある。
- MessageAttributes (デフォルト): メッセージ属性ベースのフィルタ
- MessageBody: JSONペイロードのフィールドでフィルタ (
FilterPolicyScope: MessageBodyを設定)
// 属性ベースフィルタ: priority=high/critical かつ amount>=1000 の場合のみ配信
{
"priority": ["high", "critical"],
"amount": [{"numeric": [">=", 1000]}]
}
// ペイロードベースフィルタ (MessageBody スコープ)
// サブスクリプション属性 FilterPolicyScope=MessageBody を設定後に有効
{
"eventType": ["ORDER_CREATED", "ORDER_UPDATED"],
"metadata": {
"region": [{"prefix": "ap-northeast"}]
}
}
フィルタ設計パターン:
| パターン | 記法 | 用途 |
|---|---|---|
| AND条件 | 複数フィールドを並記 | 全条件一致時のみ配信 |
| OR条件 | 同フィールドを配列で複数値指定 | いずれか一致で配信 |
| 存在チェック | [{"exists": true}] | フィールドの有無で分岐 |
| 数値範囲 | [{"numeric": [">=", 100, "<", 1000]}] | 金額・スコアの範囲指定 |
| 除外 | [{"anything-but": ["CANCELLED"]}] | 特定値を除外 |
| 前方一致 | [{"prefix": "ap-"}] | リージョン・IDプレフィックス |
Fan-outパターン実装
1つのSNS Topicから複数のサブスクライバーに並列配信する設計パターン。
# SQSサブスクリプション (バッファリング + フィルタリング)
sns.subscribe(
TopicArn=topic_arn,
Protocol='sqs',
Endpoint=sqs_queue_arn,
Attributes={
'RawMessageDelivery': 'true', # SNSラッパー除去 (コンシューマーの二重パース不要)
'FilterPolicy': json.dumps({'eventType': ['ORDER_CREATED']}),
'RedrivePolicy': json.dumps({'deadLetterTargetArn': dlq_arn})
}
)
# Lambdaサブスクリプション (即時処理)
sns.subscribe(
TopicArn=topic_arn,
Protocol='lambda',
Endpoint=lambda_function_arn,
Attributes={
'FilterPolicy': json.dumps({'priority': ['critical']})
}
)
Cross-accountサブスクリプション設計:
異なるアカウントのSQSをサブスクライブする場合、SNS側のリソースポリシーとSQS側のキューポリシーの両方が必要になる。
// SQS キューポリシー (クロスアカウントSNS許可)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"Service": "sns.amazonaws.com"},
"Action": "sqs:SendMessage",
"Resource": "arn:aws:sqs:ap-northeast-1:TARGET_ACCOUNT:target-queue",
"Condition": {
"ArnEquals": {
"aws:SourceArn": "arn:aws:sns:ap-northeast-1:SOURCE_ACCOUNT:source-topic"
}
}
}
]
}
モバイルプッシュ配信
SNSはAPNs(iOS)・FCM(Android)・ADM(Amazon)へのプッシュ通知を統一APIで提供する。
| コンポーネント | 役割 |
|---|---|
| Platform Application | APNs/FCMの認証情報 (証明書/APIキー) を保持 |
| Platform Endpoint | デバイストークンと1:1で紐付く個別エンドポイント |
| Direct Publish | Platform Endpointへのターゲット配信 |
# Platform Endpoint作成 (アプリ起動時にデバイス登録・更新)
endpoint = sns.create_platform_endpoint(
PlatformApplicationArn=platform_app_arn,
Token=device_token, # APNs/FCMデバイストークン
CustomUserData='user-id-12345'
)
# Direct Publish (マルチプラットフォーム対応)
sns.publish(
TargetArn=endpoint['EndpointArn'],
Message=json.dumps({
'GCM': json.dumps({ # FCM/Android
'notification': {
'title': '注文完了',
'body': 'ORD-12345が発送されました'
}
}),
'APNS': json.dumps({# iOS
'aps': {
'alert': {
'title': '注文完了',
'body': 'ORD-12345が発送されました'
}
}
})
}),
MessageStructure='json' # プラットフォーム別メッセージ分岐
)
Platform Endpointはデバイストークンの有効期限切れで無効化される。CreatePlatformEndpointは既存トークンに対してもべき等に動作するため、アプリ起動のたびに呼び出してエンドポイントを最新状態に保つことが推奨される。
メッセージ属性 (MessageAttributes) の活用
メッセージ属性はフィルタリングとルーティング分岐の両方に利用できる。
sns.publish(
TopicArn=topic_arn,
Message='{"orderId": "ORD-12345"}',
MessageAttributes={
'eventType': {
'DataType': 'String',
'StringValue': 'ORDER_CREATED'
},
'priority': {
'DataType': 'String',
'StringValue': 'high'
},
'amount': {
'DataType': 'Number',
'StringValue': '15000'
}
}
)
SNS + SQS Fan-outのデッドレタリング
SNSサブスクリプションレベルにDLQを設定することで、SNS→サブスクライバー間の配信失敗を捕捉できる。
# サブスクリプションにDLQ設定 (Redrive Policy)
sns.set_subscription_attributes(
SubscriptionArn=subscription_arn,
AttributeName='RedrivePolicy',
AttributeValue=json.dumps({
'deadLetterTargetArn': 'arn:aws:sqs:ap-northeast-1:123456789012:sns-dlq'
})
)
DLQ配置の二層設計:
- SNSサブスクリプションDLQ: SNS→サブスクライバー間の配信失敗を捕捉 (HTTP 5xx / SQSアクセス拒否等)
- SQSキューDLQ: コンシューマーの処理失敗を捕捉 (maxReceiveCount超過後に移動)
両方を設定しないと、どの層での失敗かが判断できず障害対応が長引く。CloudWatchで NumberOfMessagesFailed と ApproximateNumberOfMessagesNotVisible をアラーム監視する。
トピック種別選定
– 順序保証・Exactly-once が必要 → FIFO Topic (サブスクライバーはSQS FIFOのみ)
– 高スループット・Lambda直結が必要 → Standard Topic
フィルタポリシー設計
– MessageBodyスコープはサブスクリプションに FilterPolicyScope: MessageBody を明示設定
– フィルタアクション上限: 5件/秒/サブスクリプション → 大量配信時はSQSバッファを挟む
– 属性フィルタを使う場合は RawMessageDelivery: false を維持 (フィルタはSNSエンベロープの属性を参照)
Fan-out DLQ
– SNSサブスクリプションとSQSキューの両階層にDLQを設定
– CloudWatchで配信失敗数をアラーム監視
問題: SNS→SQS Fan-outでRawMessageDeliveryを設定しないと、SQSコンシューマーはSNSエンベロープ付きJSONを受け取る。コンシューマー側で json.loads(message['Body'])['Message'] という二重パースが必要になり、既存コンシューマーとの互換性が失われる。
正解パターン: サブスクリプション作成時に RawMessageDelivery: true を設定。SNSエンベロープを除去し、publishしたメッセージボディをそのままSQSに格納する。フィルタポリシーを属性ベースで使う場合のみ RawDelivery: false を維持すること。
Amazon EventBridge 本番運用 — イベントバス / Scheduler / Pipes / Schema Registry

イベントバス設計: Default vs Custom Event Bus
| 比較項目 | Default Event Bus | Custom Event Bus |
|---|---|---|
| 主用途 | AWSサービスイベント受信 | アプリケーション独自イベント |
| 共有性 | AWSサービス全体で共有 | ドメイン/環境単位で分割可能 |
| ルール上限 | 300ルール/バス | 300ルール/バス (緩和申請可) |
| アーカイブ | 一部制限あり | 全イベント対象 |
| クロスアカウント受信 | 不可 | 完全サポート |
Custom Event Bus分離戦略:
ドメイン分割: order-events-bus / payment-events-bus / notification-events-bus
環境分割: prod-events-bus / staging-events-bus
Default Event Busにアプリイベントを流すと300ルール上限に到達しやすく、AWSサービスイベントとの混在でデバッグも困難になる。新規設計ではドメイン単位のCustom Event Busを採用する。
import boto3
import json
events = boto3.client('events', region_name='ap-northeast-1')
# Custom Event Bus作成
events.create_event_bus(
Name='order-events-bus',
Tags=[{'Key': 'Domain', 'Value': 'OrderManagement'}]
)
# カスタムイベント送信 (PutEvents API)
response = events.put_events(
Entries=[
{
'EventBusName': 'order-events-bus',
'Source': 'com.example.orders', # ドット区切りの逆ドメイン記法推奨
'DetailType': 'OrderCreated',
'Detail': json.dumps({
'orderId': 'ORD-12345',
'customerId': 'CUST-789',
'amount': 15000,
'status': 'CREATED'
})
}
]
)
# FailedEntryCount > 0 で部分失敗 → 再送が必要
print(f"FailedEntryCount: {response['FailedEntryCount']}")
イベントパターン (Event Pattern) マッチング
EventBridgeのイベントパターンはJSON構造に対して高度なマッチングを行う。
{
"source": ["com.example.orders"],
"detail-type": ["OrderCreated", "OrderUpdated"],
"detail": {
"status": [{"anything-but": ["CANCELLED", "REFUNDED"]}],
"amount": [{"numeric": [">=", 1000]}],
"region": [{"prefix": "ap-northeast"}],
"requestId": [{"exists": true}]
}
}
| オペレーター | 記法 | 用途 |
|---|---|---|
| prefix | {"prefix": "ap-"} | 前方一致 (リージョン・IDプレフィックス) |
| suffix | {"suffix": "-prod"} | 後方一致 |
| anything-but | {"anything-but": ["CANCELLED"]} | 除外リスト |
| numeric | {"numeric": [">=", 0, "<", 1000]} | 数値範囲 |
| exists | {"exists": true/false} | フィールドの有無 |
| equals-ignore-case | {"equals-ignore-case": "admin"} | 大文字小文字無視 |
ルール (Rules) + ターゲット設計
Input Transformer: イベントデータをターゲット向けのフォーマットに変換する機能。
// InputPathsMap: イベントから抽出するフィールドのマッピング
{
"orderId": "$.detail.orderId",
"amount": "$.detail.amount",
"eventTime": "$.time"
}
// InputTemplate: 送信フォーマット (<変数名> でインジェクト)
{
"message": "注文 <orderId> が作成されました (金額: <amount>円)",
"timestamp": "<eventTime>"
}
DLQ on Rule (ターゲット配信失敗時の保全):
events.put_targets(
Rule='order-created-rule',
EventBusName='order-events-bus',
Targets=[
{
'Id': 'order-processor-lambda',
'Arn': lambda_function_arn,
'DeadLetterConfig': {
'Arn': dlq_arn # ターゲット配信失敗時にDLQへ退避
},
'RetryPolicy': {
'MaximumRetryAttempts': 3, # リトライ上限 (最大185)
'MaximumEventAgeInSeconds': 3600 # イベント有効期間 (最大24h)
}
}
]
)
ルール上限300件に対する設計戦略:
- イベントパターンのOR条件を活用して複数イベントタイプを1ルールで処理
- 環境ごとにCustom Event Busを分割してルール上限を独立させる
- Service Quotasで緩和申請するとバスごとの上限を引き上げ可能
EventBridge Scheduler
EventBridge Schedulerはスタンドアロンのスケジューリングサービス。EventBridgeルールのスケジュールに比べてタイムゾーン対応・Flexible Time Window・One-time実行が追加されている。
| スケジュール種別 | 記法 | 例 |
|---|---|---|
| One-time | at(yyyy-mm-ddThh:mm:ss) | at(2026-06-01T09:00:00) |
| Rate | rate(N unit) | rate(5 minutes) |
| Cron | cron(分 時 日 月 曜 年) | cron(0 0 * * ? *) |
scheduler = boto3.client('scheduler', region_name='ap-northeast-1')
# Cron スケジュール (毎日9時 JST)
scheduler.create_schedule(
Name='daily-report-job',
ScheduleExpression='cron(0 0 * * ? *)', # UTC 0:00 = JST 9:00
ScheduleExpressionTimezone='Asia/Tokyo', # タイムゾーン指定 (Schedulerのみ対応)
Target={
'Arn': lambda_function_arn,
'RoleArn': scheduler_role_arn,
'Input': json.dumps({'reportType': 'daily'}),
'RetryPolicy': {
'MaximumRetryAttempts': 2,
'MaximumEventAgeInSeconds': 1800
}
},
FlexibleTimeWindow={
'Mode': 'FLEXIBLE',
'MaximumWindowInMinutes': 15 # 0-15分内のランダム実行 (雷群れ問題回避)
},
State='ENABLED'
)
Flexible Time Window: 同時刻に多数のスケジュールが起動してバックエンドが過負荷になる「雷群れ問題 (Thundering Herd)」を回避するため、指定ウィンドウ内でランダムに実行タイミングをずらす機能。
EventBridge Pipes
Pipesは Source → Enrichment → Target の直線型パイプラインを宣言的に構成する。
[Source] [Filter] [Enrichment] [Target]
SQS / Kinesis →イベントフィルタ → Lambda→ Lambda
DynamoDB Streams (不要レコード除外)Step Functions SQS / SNS
Kafka / Amazon MQAPI Gateway EventBridge
pipes = boto3.client('pipes', region_name='ap-northeast-1')
pipes.create_pipe(
Name='order-enrichment-pipe',
Source=sqs_queue_arn,
SourceParameters={
'SqsQueueParameters': {
'BatchSize': 10,
'MaximumBatchingWindowInSeconds': 5
},
'FilterCriteria': {
'Filters': [
{'Pattern': '{"body": {"eventType": ["ORDER_CREATED"]}}'}
]
}
},
Enrichment=lambda_enrichment_arn, # 注文詳細を外部DBから補完
EnrichmentParameters={
'InputTemplate': '{"orderId": "<$.body.orderId>"}'
},
Target=event_bus_arn,
TargetParameters={
'EventBridgeEventBusParameters': {
'DetailType': 'EnrichedOrderEvent',
'Source': 'com.example.pipes'
}
},
RoleArn=pipe_role_arn
)
Pipesの代表的なユースケース:
- DynamoDB Streams → Lambda → SNS: テーブル変更イベントをフィルタ・エンリッチしてSNS配信
- SQS → Lambda → EventBridge: キューメッセージを構造化イベントに変換して再配布
- Kinesis → API Gateway: ストリームレコードをリアルタイムで外部APIに転送
Schema Registry
Schema Registryはイベントスキーマの自動検出・管理・型安全なコード生成を提供する。
# Custom Event Busにスキーマディスカバラーをアタッチ
aws schemas create-discoverer \
--source-arn arn:aws:events:ap-northeast-1:123456789012:event-bus/order-events-bus \
--description "Order events schema discoverer"
イベントを数回送信するとSchema Registryが自動でスキーマを推定・登録する。その後コードバインディングを生成して型安全なコードを取得する。
# Python コードバインディング生成
aws schemas get-code-binding-source \
--registry-name discovered-schemas \
--schema-name "com.example.orders@OrderCreated" \
--language Python36 \
--output text > order_created_schema.py
生成コードはOpenAPI 3.0互換スキーマを基にしており、Pythonではデータクラスとして定義される。Java/TypeScriptも同様の型安全クラスが生成される。スキーマのバージョン管理もRegistry側で自動追跡されるため、イベント仕様の変更履歴を一元管理できる。
SaaS Partner統合
EventBridgeはSaaSパートナーのイベントをネイティブに受信できる。
| SaaSパートナー | ユースケース例 |
|---|---|
| Zendesk | チケット作成/更新 → Lambda でCRM自動同期 |
| Datadog | モニタリングアラート → SNS でチーム通知 |
| PagerDuty | インシデント → Step Functions で自動対応 |
| Salesforce | リード/商談イベント → SQS でバッチ処理 |
| GitHub | PRイベント → Lambda でCI/CD自動起動 |
SaaS側でEventBridgeイベントソースを設定し、AWSコンソールでパートナーイベントソースを紐付けたCustom Event Busを作成するだけで受信可能になる。追加インフラは不要。
EventBridge Archive & Replay
アーカイブ機能でイベントを長期保持し、必要に応じてリプレイ (再生) することでバグ修正後の再処理が可能になる。
# Custom Event Busにアーカイブ設定
events.create_archive(
ArchiveName='order-events-archive',
EventSourceArn=custom_event_bus_arn,
Description='30日間イベント保持',
EventPattern=json.dumps({'source': ['com.example.orders']}),
RetentionDays=30 # 0=無期限
)
# アーカイブからリプレイ (バグ修正後の再処理)
from datetime import datetime, timezone
events.start_replay(
ReplayName='replay-2026-05-01-range',
Description='バグ修正後の再処理',
EventSourceArn='arn:aws:events:ap-northeast-1:123456789012:archive/order-events-archive',
EventStartTime=datetime(2026, 5, 1, 0, 0, 0, tzinfo=timezone.utc),
EventEndTime=datetime(2026, 5, 2, 0, 0, 0, tzinfo=timezone.utc),
Destination={
'Arn': custom_event_bus_arn # 再生先のEvent Bus
}
)
リプレイ時の注意点:
- リプレイイベントは通常イベントと同じルールで処理される → ターゲットが同じアクションを再実行するため、べき等設計が必須
replay-nameフィールドがイベントに付与されるため、Lambda側でリプレイフラグを検出して処理分岐が可能- 保持期間
RetentionDays: 0(無期限) はストレージコストが継続増加するため、コンプライアンス要件と照らして期間を設定する
| 比較項目 | EventBridge Rules (スケジュール) | EventBridge Scheduler |
|———|——————————-|———————-|
| タイムゾーン指定 | 不可 (UTC固定) | 可能 |
| Flexible Time Window | なし | あり |
| One-time実行 | 不可 | 可能 |
| IAMロール指定 | なし (EventBridgeが自動管理) | 必須 |
| ターゲット数/設定 | 5つ/ルール | 1つ/スケジュール |
推奨: 新規実装はEventBridge Schedulerを採用。タイムゾーン対応・Flexible Time Window・One-time実行が必要な場合はScheduler一択。既存のEventBridgeルールベースのスケジュールは機能的に問題がなければ移行コストに見合わない場合もある。
イベントバス設計
– Default Event Busにアプリイベントを流さない (ノイズ増加・300ルール制限に到達しやすい)
– ドメイン/環境単位でCustom Event Busを作成してルール上限を独立させる
ルール・ターゲット設計
– 1バス300ルール上限 → OR条件活用 + ドメイン分割で回避
– DLQ on Ruleを全ターゲットに設定し配信失敗を確実にキャプチャ
– RetryPolicyでMaximumRetryAttempts・MaximumEventAgeInSecondsを要件に合わせて設定
Archive & Replay 運用
– 本番バスには必ずアーカイブを設定 (バグ修正後の再処理コストがゼロに)
– リプレイ時はターゲットのべき等性を事前確認
– 保持期間はコスト・コンプライアンス要件で決定 (0=無期限はコスト注意)
Amazon API Gateway 本番運用 — REST vs HTTP API / 認可統合 / スロットリング

REST API vs HTTP API — 7軸選定ガイド
REST APIとHTTP APIはユースケースで使い分ける。以下7軸で最適解を選定する。
| 選定軸 | REST API | HTTP API |
|---|---|---|
| 認可方式 | Cognito / Lambda Authorizer / IAM / API Key | JWT Authorizer / Lambda Authorizer / IAM |
| プロキシ統合 | Lambda Proxy / AWS統合 / VPC Link (NLB) | Lambda Proxy / HTTP Proxy / VPC Link (ALB/NLB/CloudMap) |
| 料金体系 | $3.50/100万リクエスト | $1.00/100万リクエスト |
| スループット上限 | 10,000 rps (アカウント上限・ステージ分割可) | 10,000 rps (調整可) |
| WebSocket対応 | 別途WebSocket API | 別途WebSocket API |
| カスタムドメイン | Edge / Regional 両対応 | Regional のみ |
| リクエスト検証 | モデル / パラメータ Validator | 非対応 (バックエンド実装) |
REST APIは認証統合の複雑さ・リクエスト検証・レスポンスキャッシュ・API Key管理が必要なエンタープライズ向けに適する。HTTP APIはコスト最優先・JWT認証で十分なシンプルユースケース向けで、料金はREST APIの約1/3。
移行前に以下の機能依存を確認する。
– 要再実装: リクエスト検証 (Validator)・Usage Plan・レスポンスキャッシュ
– そのまま移行: Lambda Proxy統合・カスタムドメイン (Regional)・CloudWatch Logs
– コスト削減試算: 月間10億リクエストで年間約$30,000差。機能要件と削減額を比較してから判断する
ステージ管理 — Stage Variables / Canary Release
3ステージ運用パターン
# Stage Variables設定例 (CloudFormation)
RestApiStage:
Type: AWS::ApiGateway::Stage
Properties:
RestApiId: !Ref RestApi
StageName: prod
Variables:
lambdaAlias: prod
backendUrl: "https://api.example.com"
MethodSettings:
- ResourcePath: "/*"
HttpMethod: "*"
ThrottlingBurstLimit: 500
ThrottlingRateLimit: 1000
Stage VariablesでステージごとにLambdaエイリアスやバックエンドURLを差し替える。Lambda統合では arn:aws:lambda:region:account:function:MyFunc:${stageVariables.lambdaAlias} の形式で参照する。dev/stg/prodの3ステージに異なるエイリアス(dev/stg/prod)を割り当て、環境差異をコード変更なしに吸収する。
Canaryデプロイ
{
"canarySettings": {
"percentTraffic": 10,
"deploymentId": "abc123def456",
"stageVariableOverrides": {
"lambdaAlias": "canary"
},
"useStageCache": false
}
}
percentTraffic: 10 でリクエストの10%をCanaryデプロイに流す。エラー率・レイテンシが正常範囲内であれば UpdateStage でCanary割合を0にして本番切り替えを完了する。ロールバックは percentTraffic を0に戻すだけでよく、Lambdaエイリアス切り戻しと組み合わせると即時復旧できる。
認可統合
Cognito User Pool Authorizer
CognitoAuthorizer:
Type: AWS::ApiGateway::Authorizer
Properties:
RestApiId: !Ref RestApi
Name: CognitoAuth
Type: COGNITO_USER_POOLS
IdentitySource: method.request.header.Authorization
ProviderARNs:
- !GetAtt UserPool.Arn
クライアントはAuthorizationヘッダにCognito IDトークン(JWT)を付与して送信する。API GatewayがJWT署名・issuer・audienceを自動検証するため、バックエンドLambdaは認証ロジックを実装しなくてよい。
Lambda Authorizer
| 種別 | IdentitySource | 用途 |
|---|---|---|
| Token型 | BearerトークンSS (Authorizationヘッダ) | OAuth2/JWT独自検証 |
| Request型 | ヘッダ・クエリ・コンテキスト複合 | IP制限・複合条件認可 |
AuthorizerはIAMポリシーを返す。TTL設定(デフォルト300秒)でLambda呼び出しコストとレイテンシを削減する。
def lambda_handler(event, context):
token = event["authorizationToken"]
if is_valid(token):
return {
"principalId": "user",
"policyDocument": {
"Version": "2012-10-17",
"Statement": [{
"Action": "execute-api:Invoke",
"Effect": "Allow",
"Resource": event["methodArn"]
}]
}
}
raise Exception("Unauthorized")
IAM認可 (Signature V4)
AWS_IAM認可タイプを設定するとSigV4署名が必須になる。ECS→API Gatewayなどサービス間通信に適する。クライアントはAWS SDKのSigV4署名機能かrequests-aws4authライブラリを使用する。
API Key + Usage Plan
# API Key作成とUsage Plan関連付け
aws apigateway create-api-key --name "partner-key" --enabled
aws apigateway create-usage-plan \
--name "partner-plan" \
--throttle burstLimit=100,rateLimit=50 \
--quota limit=10000,period=MONTH
aws apigateway create-usage-plan-key \
--usage-plan-id <planId> \
--key-id <keyId> \
--key-type API_KEY
Usage PlanはパートナーやAPIクライアント単位でレート制限とクォータを設定する手段として使う。API Keyはx-api-keyヘッダで送信する。
スロットリング設計
スロットリングは3階層で制御する。
| 階層 | 設定箇所 | デフォルト上限 |
|---|---|---|
| アカウントレベル | サービスクォータ | 10,000 rps / 5,000 バースト |
| ステージレベル | Stage > Default Method Throttling | アカウント上限を複数ステージで分割 |
| メソッドレベル | Stage > Method Settings | ステージ設定を上書き |
アカウントレベルの上限はService Quotasから引き上げ申請が可能。ステージごとに上限を分割し、特定エンドポイントへの集中を防ぐ。書き込み系APIのメソッドレベル制限を絞り込むことで読み取り系の安定性を保証できる。
# CDK: メソッドレベルスロットリング
const api = new apigateway.RestApi(this, "MyApi");
const orders = api.root.addResource("orders");
orders.addMethod("POST", lambdaIntegration);
const stage = api.deploymentStage;
stage.addMethodSettings("POST", "/orders", {
throttlingBurstLimit: 50,
throttlingRateLimit: 20,
});
レスポンスキャッシュ (REST API専用)
RestApiStage:
Type: AWS::ApiGateway::Stage
Properties:
CacheClusterEnabled: true
CacheClusterSize: "0.5"# 0.5/1.6/6.1/13.5/28.4/58.2/118/237 GB
MethodSettings:
- ResourcePath: "/products"
HttpMethod: "GET"
CachingEnabled: true
CacheDataEncrypted: true
CacheTtlInSeconds: 300
キャッシュキーはデフォルトでURLパスパラメータとクエリ文字列を含む。クライアントからの強制無効化は Cache-Control: max-age=0 ヘッダを付与することで実現する(メソッド設定でInvalidateCache権限を許可する必要あり)。HTTP APIはキャッシュ機能を持たないため、CloudFrontを前段に置くことで代替する。
キャッシュクラスターはステージ単位で時間課金される。0.5GBで月間約$14。ステージ削除後もキャッシュ設定が残っていると課金継続するため、不要ステージのキャッシュは CacheClusterEnabled: false で明示的に無効化する。本番環境では CacheDataEncrypted: true を必ず設定する。
カスタムドメイン + ACM + Route 53
# 1. ACM証明書発行 (Regionalタイプはデプロイリージョン、Edgeはus-east-1必須)
aws acm request-certificate \
--domain-name "api.example.com" \
--validation-method DNS \
--region ap-northeast-1
# 2. カスタムドメイン作成
aws apigateway create-domain-name \
--domain-name "api.example.com" \
--endpoint-configuration types=REGIONAL \
--regional-certificate-arn arn:aws:acm:ap-northeast-1:123456789:certificate/xxxx
# 3. APIマッピング (ベースパスでバージョン管理)
aws apigateway create-base-path-mapping \
--domain-name "api.example.com" \
--rest-api-id <apiId> \
--stage prod \
--base-path "v1"
Route 53ではALIASレコード(AレコードまたはAAAAレコード)でカスタムドメインのRegionalDomainNameをターゲットに設定する。Edgeタイプは証明書をus-east-1で発行が必須。ベースパスマッピングによりapi.example.com/v1とapi.example.com/v2で異なるAPIステージを同一ドメインで運用できる。
VPC Link — プライベート統合
# REST API: NLB経由VPC Link
VpcLink:
Type: AWS::ApiGateway::VpcLink
Properties:
Name: my-vpc-link
TargetArns:
- !GetAtt NetworkLoadBalancer.LoadBalancerArn
# HTTP API: ALB/NLB/CloudMap対応
HttpApiVpcLink:
Type: AWS::ApiGatewayV2::VpcLink
Properties:
Name: http-api-vpc-link
SubnetIds:
- !Ref PrivateSubnetA
- !Ref PrivateSubnetB
SecurityGroupIds:
- !Ref VpcLinkSg
VPC Linkを使うとインターネットを経由せずVPC内のプライベートリソース(ALB/NLB/ECS)へルーティングできる。REST APIはNLBのみ対応。HTTP APIはALB・NLB・Cloud Map(ECSサービスディスカバリ)に対応し、より柔軟なプライベート統合が可能。ECSサービスはCloud MapでVPCリンク経由で公開することでAPI Gatewayから直接到達できる。
アクセスログとモニタリング
{
"requestId": "$context.requestId",
"ip": "$context.identity.sourceIp",
"httpMethod": "$context.httpMethod",
"resourcePath": "$context.resourcePath",
"status": "$context.status",
"responseLatency": "$context.responseLatency",
"integrationLatency": "$context.integrationLatency",
"authorizerError": "$context.authorizer.error"
}
アクセスログはCloudWatch LogsまたはKinesis Data Firehoseへ転送できる。上記JSON形式はAthenaでのアドホック分析とCloudWatch Logs Insightsのレイテンシ集計に適する。
推奨モニタリングメトリクス:
| メトリクス | 用途 |
|---|---|
4XXError | クライアントエラー率 (認可失敗・バリデーションエラー検知) |
5XXError | バックエンドエラー率 |
Latency | エンドツーエンドレイテンシ (p99監視推奨) |
IntegrationLatency | バックエンド (Lambda等) のレイテンシ |
Count | リクエスト総数 (スロットリング設計の基準値) |
アクセス制御 — リソースポリシーとVPCエンドポイント
リソースポリシーを使用してIPアドレス・VPCエンドポイント単位でAPIへのアクセスを制限する。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:ap-northeast-1:123456789:api-id/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": ["203.0.113.0/24", "198.51.100.0/24"]
}
}
}
]
}
VPCエンドポイントポリシーと組み合わせることで、特定のVPCからのみAPIアクセスを許可するプライベートAPIを構成できる。外部からの不正アクセス遮断にはリソースポリシーによるIP制限・VPCエンドポイント制限が第一選択肢。トラフィック全体へのルールベース検査が必要な場合は、API GatewayへのAWS WAFアタッチメントを補完的に検討する。
AWS AppSync 本番運用 — GraphQLスキーマ / リゾルバ / リアルタイムサブスクリプション
sequenceDiagram
participant Client
participant AppSync as AWS AppSync
participant Resolver as Resolver Pipeline
participant DDB as DynamoDB
participant Lambda as Lambda Function
Client->>AppSync: GraphQL Query/Mutation
AppSync->>Resolver: Pipeline実行
Resolver->>DDB: データ取得/更新
Resolver->>Lambda: カスタムロジック
Resolver-->>AppSync: レスポンス集約
AppSync-->>Client: JSON Response
Note over Client,AppSync: Subscription (WebSocket)<br/>リアルタイム更新通知
GraphQLスキーマ設計 — スキーマファーストアプローチ
AppSyncはスキーマファーストアプローチを採用する。GraphQL SDL(Schema Definition Language)でAPIの型・クエリ・ミューテーション・サブスクリプションを定義し、各フィールドにリゾルバをアタッチしてデータソースと接続する。
Type / Query / Mutation / Subscription 基本構造
type Todo {
id: ID!
title: String!
completed: Boolean!
owner: String!
createdAt: AWSDateTime!
}
type TodoConnection {
items: [Todo]
nextToken: String
}
type Query {
getTodo(id: ID!): Todo
listTodos(limit: Int, nextToken: String): TodoConnection
}
type Mutation {
createTodo(title: String!, completed: Boolean): Todo
updateTodo(id: ID!, completed: Boolean!): Todo
deleteTodo(id: ID!): Todo
}
type Subscription {
onCreateTodo: Todo @aws_subscribe(mutations: ["createTodo"])
onUpdateTodo: Todo @aws_subscribe(mutations: ["updateTodo"])
}
ページネーション — nextToken パターン
大量データを取得する場合、DynamoDBのLastEvaluatedKeyをBase64エンコードしたnextTokenを返す。クライアントは次のリクエストでnextTokenを指定することで続きのアイテムを取得する。全件取得ループはクライアント側で実装する。
type ItemConnection {
items: [Item]
nextToken: String
}
type Query {
listItems(
filter: ModelItemFilterInput
limit: Int
nextToken: String
): ItemConnection
}
リゾルバ — Unit / Pipeline / Direct Lambda
リゾルバはGraphQLフィールドとデータソースを接続するロジックを定義する。AppSyncでは3種類のリゾルバが利用可能で、ユースケースに応じて使い分ける。
Unit Resolver
1フィールドに対して1つのデータソース操作を実行するシンプルなリゾルバ。DynamoDBのGetItemやPutItemなど単純なCRUD操作に適する。
Pipeline Resolver
複数のFunction(パイプライン関数)を順番に実行し、前のFunctionの出力を次のFunctionの入力として渡す。「認可チェック → データ取得 → 後処理」のような複数ステップを組み合わせる場合に有効。
JavaScript Resolver — VTLからの移行
AppSyncは2022年よりJavaScript/TypeScriptベースのリゾルバをGAリリース。従来のVTL(Velocity Template Language)と比べてデバッグが容易で、型安全な開発が可能になった。新規プロジェクトではJavaScript Resolverを標準とする。
import { util } from "@aws-appsync/utils";
export function request(ctx) {
return {
operation: "GetItem",
key: util.dynamodb.toMapValues({ id: ctx.args.id }),
};
}
export function response(ctx) {
if (ctx.error) {
util.error(ctx.error.message, ctx.error.type);
}
return ctx.result;
}
Direct Lambda Resolver
LambdaをデータソースとしてAppSyncが直接呼び出す方式。VTL/JSのマッピングテンプレート記述を省略でき、Lambda関数のハンドラにfieldNameとargumentsが渡される。複雑なビジネスロジックや外部API連携に適する。
データソース別選定指針
| データソース | 典型ユースケース | 注意点 |
|---|---|---|
| DynamoDB | プロファイル・タスク管理・設定保存 | トランザクション操作はPipeline Resolver必須 |
| RDS (Aurora Serverless v2) | リレーショナルクエリ・レポート生成 | コールドスタートとコネクション上限に注意 |
| Lambda | 複雑なビジネスロジック・外部API連携 | タイムアウト管理が重要(最大30秒) |
| HTTP | 外部RESTエンドポイント呼び出し | エラーハンドリングを丁寧に実装 |
| OpenSearch | 全文検索・ファセット集計 | DynamoDBとの二重書きアーキテクチャが基本 |
| シナリオ | 推奨リゾルバ | 理由 |
|———|————|——|
| 単一DynamoDB操作 | Unit Resolver (JS) | シンプル・高速 |
| 認可チェック→データ取得→変換 | Pipeline Resolver | 複数Functionを順次実行 |
| 複雑なビジネスロジック | Direct Lambda Resolver | Lambdaで自由に実装 |
| 外部REST API呼び出し | HTTP データソース | VTL/JSでリクエスト/レスポンスを変換 |
| 全文検索 | OpenSearch データソース | DynamoDBと二重書き構成を併用 |
新規プロジェクトはJavaScript Resolverを選択。VTLは既存資産がある場合のみ継続。
リアルタイムサブスクリプション — WebSocket接続管理
AppSyncのサブスクリプションはWebSocketを通じて実装される。クライアントがsubscribe操作でWebSocket接続を確立すると、指定したMutationが実行されるたびにリアルタイムで更新が配信される。AppSyncがWebSocket接続の管理・スケーリングを自動で処理するため、独自のWebSocketサーバー管理は不要になる。
@aws_subscribe ディレクティブ
スキーマのSubscriptionタイプに@aws_subscribeディレクティブを付与し、購読するMutation名を指定する。
type Subscription {
onCreateTodo: Todo
@aws_subscribe(mutations: ["createTodo"])
onUpdateTodo: Todo
@aws_subscribe(mutations: ["updateTodo"])
onDeleteTodo: Todo
@aws_subscribe(mutations: ["deleteTodo"])
@aws_auth(cognito_groups: ["Admins"])
}
Enhanced Subscription Filtering
サーバーサイドフィルタリングにより、各クライアントは自身に関連するイベントのみを受け取る。フィルタはリゾルバ内で定義でき、接続ごとに動的な条件を設定できる。
export function request(ctx) {
return { payload: null };
}
export function response(ctx) {
const filter = {
owner: { eq: ctx.identity.username },
};
extensions.setSubscriptionFilter(
util.transform.toSubscriptionFilter(filter)
);
return null;
}
Merged API — マイクロサービス間のスキーマ統合
Merged APIは複数のAppSync API(Source API)のスキーマを1つのエンドポイントに統合する機能。各チームが独立して自サービスのスキーマを管理しながら、クライアントには単一のGraphQL APIを提供できる。
| 概念 | 説明 |
|---|---|
| Source API | 各マイクロサービスが独立管理するAppSync API |
| Merged API | 複数Source APIを統合した単一エンドポイント |
| MergingBehavior | AUTO_MERGE推奨(型衝突は手動解決が必要) |
| 更新タイミング | Source API更新後、Merged APIの再マージが必要 |
サーバーサイドキャッシュ
AppSyncのキャッシュは内部的にElastiCacheを使用し、同一クエリへの重複データソースアクセスを削減する。
| キャッシュタイプ | 対象 | 適用場面 |
|---|---|---|
| Full Request Cache | クエリ全体 | 同一クエリ+変数の組合せをまとめてキャッシュ |
| Per-resolver Cache | リゾルバ単位 | フィールドレベルで細かく制御したい場合 |
{
"ttl_recommendations": {
"マスタデータ(ほぼ変更なし)": "3600秒",
"ユーザープロファイル(低頻度更新)": "300秒",
"リアルタイム性が求められるデータ": "0(Per-resolver TTLを0に設定)"
}
}
認可 — 5方式とMulti-auth設計
AppSyncは最大5つの認可方式を同時設定できる(マルチ認証)。プライマリ認証を1つ設定し、残りはセカンダリ認証として追加する。
| 認可タイプ | 典型ユースケース | 特徴 |
|---|---|---|
| API_KEY | パブリックAPI・開発テスト | 有効期限365日まで。本番での単独使用は非推奨 |
| AWS_IAM | バックエンドサービス間通信 | SigV4署名が必要。マシン間通信の標準 |
| OPENID_CONNECT | Auth0等サードパーティIdP | JWTトークンで認証 |
| AMAZON_COGNITO_USER_POOLS | エンドユーザー認証 | Cognitoユーザープールと直接統合 |
| AWS_LAMBDA | カスタム認可ロジック | Lambda関数で任意の認証/認可ロジックを実装 |
type Query {
getMyProfile: User @aws_cognito_user_pools
listPublicPosts: [Post] @aws_api_key
adminGetUser(id: ID!): User @aws_iam
}
1. プライマリ認証は Cognito User Pools — エンドユーザー向けAPIの標準構成
2. バックエンド連携は AWS_IAM — SigV4署名でサービス間認証。APIキー共有を排除
3. カスタムロジックは AWS_LAMBDA — 外部IdP統合・IP制限・レートリミット等を実装
Multi-auth設定後は@aws_authディレクティブでフィールドレベルのアクセス制御を追加し、認可漏れを防ぐ。
詰まりポイント7選 + アンチパターン→正解パターン変換
詰まり1 — SQS Visibility Timeout 不足で同一メッセージ二重処理
症状: 同一メッセージがLambdaで複数回処理され、データの重複が発生する。
原因: Lambda関数の処理時間がSQSのVisibility Timeoutを超えた場合、メッセージが再度キューに表示され、別のLambdaインスタンスが同じメッセージを取得する。デフォルトのVisibility Timeout は30秒で、長時間バッチ処理では不足しやすい。
解決策:
– VisibilityTimeoutをLambdaタイムアウトの6倍以上に設定(Lambda 5分 → SQS 30分以上)
– 処理時間が変動する場合はLambda内からChangeMessageVisibility APIを呼び出して動的に延長
– 冪等性設計(DynamoDBの条件付き書き込み等)でダブル処理を許容する設計も有効
{
"VisibilityTimeout": 1800,
"_comment": "Lambdaタイムアウト5分の場合: 5分×6倍=30分=1800秒"
}
詰まり2 — SNS サブスクリプションフィルタ誤設定でメッセージ消失
症状: SNSにメッセージをPublishしているのに、SQS/Lambdaにメッセージが届かない。SNSコンソール上は送信成功になっている。
原因: サブスクリプションにフィルタポリシーを設定した場合、メッセージ属性が存在しないか値が一致しないメッセージは静かに破棄される。CloudWatch MetricsのNumberOfNotificationsFilteredOutで確認できるが、ログには何も残らない。
解決策:
– フィルタポリシー設定後はCloudWatch MetricsのNumberOfNotificationsFilteredOutを必ず監視
– PublisherがMessageAttributesを正しく付与しているかデバッグ時に確認
– フィルタなしサブスクリプションをDLQ向けに追加して破棄されたメッセージをモニタリング
import boto3
sns_client = boto3.client("sns")
# フィルタポリシーの値と一致するMessageAttributesを付与
response = sns_client.publish(
TopicArn="arn:aws:sns:ap-northeast-1:123456789012:MyTopic",
Message="payload",
MessageAttributes={
"eventType": {
"DataType": "String",
"StringValue": "ORDER_CREATED",
}
},
)
詰まり3 — EventBridge イベントパターン不一致で静かに捨てられる
症状: EventBridgeルールにイベントを送信しているが、ターゲット(Lambda/SQS等)が一度も呼ばれない。
原因: EventBridgeのイベントパターンは部分一致ではなく完全一致で評価される。sourceやdetail-typeが大文字小文字を含めて完全に一致しないとルールはマッチしない。またdetailフィールドの構造がイベントと異なる場合も静かに無視される。
解決策:
– AWSコンソールの「Test event pattern」機能でイベントJSONとパターンの一致を確認
– デバッグ用にすべてのイベントをキャッチするルールを追加してCloudWatch Logsに転送
– aws events test-event-patternコマンドでCLIから確認
{
"source": ["myapp.orders"],
"detail-type": ["OrderCreated"],
"detail": {
"status": ["CONFIRMED"]
}
}
詰まり4 — API Gateway スロットリング未設定でバースト時429/502
症状: 負荷テスト時や一時的なバースト時に429 Too Many RequestsまたはLambdaで502 Bad Gatewayが発生する。
原因: API Gatewayのデフォルトスロットリングはアカウントレベル(10,000 req/s、バースト5,000)でのみ設定されており、個別APIやステージのスロットリングは未設定のことが多い。LambdaのConcurrency制限に先に達してしまう場合もある。
解決策:
– ステージレベルのデフォルトスロットリングを設定(rate/burst)
– 重要なリソースパスにはメソッドレベルのスロットリングを個別設定
– Lambda reserved concurrencyと合わせてリソース容量を設計する
{
"throttle": {
"rateLimit": 1000,
"burstLimit": 2000,
"_comment": "ステージレベルのデフォルトスロットリング設定"
}
}
詰まり5 — AppSync Resolver VTL構文エラーでGraphQL null応答
症状: AppSync GraphQLクエリでnullが返り、エラーメッセージも不明瞭。CloudWatch LogsにTemplateProcessingExceptionが記録されている。
原因: VTL(Velocity Template Language)のリクエスト/レスポンスマッピングテンプレートに構文エラーがある場合、AppSyncはフィールドをnullとして返す。エラーはerrors配列に含まれるが、クライアント側でのエラーハンドリングが不十分だと見落としやすい。
解決策:
– CloudWatch LogsのフィールドログレベルをALLに設定してVTLのデバッグ情報を確認
– AWSコンソールの「Query」タブでクエリ結果のerrorsフィールドを確認
– 新規プロジェクトはVTLをJavaScript Resolverに移行してデバッグ容易性を向上
// JavaScript Resolverでエラーを明示的にスロー
export function response(ctx) {
if (ctx.error) {
util.error(ctx.error.message, ctx.error.type, ctx.result);
}
return ctx.result;
}
詰まり6 — SQS FIFO MessageGroupId設計ミスで全キュー直列化
症状: SQS FIFOキューのスループットが極端に低い。メッセージが高速で届くはずなのに処理が追いつかない。
原因: SQS FIFOキューは同一MessageGroupId内でメッセージの順序を保証するため、同一グループのメッセージは直列に処理される。MessageGroupIdを"default"や固定値1つに設定すると、全てのメッセージが1グループになり完全直列化する。
解決策:
– MessageGroupIdはメッセージの独立処理単位(ユーザーID・注文ID等)に設定
– 異なるグループのメッセージはLambdaで並列処理(最大300コンカレントポーリング)
– FIFOが不要ならStandardキューに変更してスループットを最大化
import boto3
sqs_client = boto3.client("sqs")
# 良い設計: user_idをMessageGroupIdに使用してユーザーごとに独立
sqs_client.send_message(
QueueUrl="https://sqs.ap-northeast-1.amazonaws.com/123456789012/MyFIFO.fifo",
MessageBody=order_payload,
MessageGroupId=f"user-{user_id}",
MessageDeduplicationId=str(order_id),
)
詰まり7 — EventBridge Archive未設定でイベント再生不能
症状: バグ修正後にイベントを再処理したいが、過去のイベントデータが存在せず再処理できない。
原因: EventBridgeのArchiveは明示的に設定しないとイベントが保存されない。デフォルトでは送信後のイベントは即時破棄される。本番環境でのデバッグや障害復旧時にイベント再生が必要になることは多い。
解決策:
– カスタムイベントバスと合わせてArchiveを設定(保存期間は最低30日を推奨)
– イベントパターンフィルタで必要なイベントのみArchiveしてコスト最適化
– 復旧時はaws events start-replayでArchiveからイベントを再実行
{
"ArchiveName": "MyBusArchive",
"EventSourceArn": "arn:aws:events:ap-northeast-1:123456789012:event-bus/MyBus",
"RetentionDays": 90,
"EventPattern": "{}"
}
アンチパターン→正解パターン変換 演習5問
本番環境で頻繁に見られるアンチパターンと、その正解パターンを示す。それぞれのパターンを理解し、自社の構成を点検してほしい。
演習1: SQS — 受信数上限なしでメッセージがDLQに移動しない
{
"_comment": "❌ アンチパターン: RedrivePolicy未設定(メッセージが永久にキューに残る)",
"QueueName": "MyQueue",
"RedrivePolicy": null
}
{
"_comment": "✅ 正解パターン: DLQとmaxReceiveCountを設定",
"QueueName": "MyQueue",
"RedrivePolicy": {
"deadLetterTargetArn": "arn:aws:sqs:ap-northeast-1:123456789012:MyQueue-DLQ",
"maxReceiveCount": 3
}
}
演習2: SNS — MessageAttributes なしでフィルタポリシーを設定
# ❌ アンチパターン: メッセージ属性を付与せずに発行
# フィルタポリシーにマッチせずメッセージが破棄される
sns_client.publish(
TopicArn="arn:aws:sns:ap-northeast-1:123456789012:MyTopic",
Message="payload",
)
# ✅ 正解パターン: フィルタポリシーに対応したメッセージ属性を付与
sns_client.publish(
TopicArn="arn:aws:sns:ap-northeast-1:123456789012:MyTopic",
Message="payload",
MessageAttributes={
"eventType": {
"DataType": "String",
"StringValue": "ORDER_CREATED",
}
},
)
演習3: EventBridge — ルールが汎用的すぎて意図しないイベントをキャッチ
{
"_comment": "❌ アンチパターン: sourceのみ指定でdetail-typeを限定しない",
"source": ["aws.ec2"]
}
{
"_comment": "✅ 正解パターン: detail-typeとdetail.stateで絞り込み",
"source": ["aws.ec2"],
"detail-type": ["EC2 Instance State-change Notification"],
"detail": {
"state": ["terminated"]
}
}
演習4: API Gateway — 環境をハードコードしてステージ変数を使わない
# ❌ アンチパターン: バックエンドURLをハードコード
# Uri: "https://prod-api.example.com/endpoint"
# ✅ 正解パターン: ステージ変数でデプロイ環境を切り替え
Uri: !Sub "https://${stageVariables.backendHost}/endpoint"
# ステージ変数 backendHost に dev/stg/prod で異なる値を設定
演習5: AppSync — 全リゾルバにAPI_KEY認証のみ設定
# ❌ アンチパターン: 全フィールドにAPI_KEYのみ — 認可が実質ない
type Query {
listAllUsers: [User] @aws_api_key
getMyProfile: User@aws_api_key
adminGetStats: Stats @aws_api_key
}
# ✅ 正解パターン: 用途別に認可方式を使い分け
type Query {
listPublicItems: [Item] @aws_api_key
getMyProfile: User @aws_cognito_user_pools
adminGetStats: Stats @aws_iam
}
まとめ — Application Integration Vol1 起点宣言 + 全軸クロスリンク
§8-1: 5サービス要点まとめ表
Application Integration Vol1で取り上げた5サービスの要点を一覧にまとめる。サービス選定や本番運用時の参照テーブルとして活用してほしい。
| サービス | 主要ユースケース | 選定基準 | 本番運用キーポイント |
|---|---|---|---|
| Amazon SQS | 非同期処理・メッセージキューイング・Lambda統合 | 順序保証が必要→FIFO、それ以外→Standard | Visibility Timeout=Lambdaタイムアウト×6倍以上・DLQ必須・Long Polling設定 |
| Amazon SNS | Pub/Sub・Fan-out・モバイルプッシュ | 複数エンドポイントへの同時配信→SNS | サブスクリプションフィルタ設定時はMessageAttributes必須・FIFO TopicはSQSのみ対応 |
| Amazon EventBridge | イベント駆動アーキテクチャ・スケジュール実行・SaaS統合 | ルールベースのルーティング・Schema Registry活用 | Archive設定必須・イベントパターンの完全一致検証・Pipes活用でコード削減 |
| Amazon API Gateway | REST/HTTP APIの公開・管理・認可統合 | 低レイテンシ→HTTP API、拡張機能→REST API | ステージレベルスロットリング設定・認可統合設計・キャッシュ活用 |
| AWS AppSync | GraphQL API・リアルタイムサブスクリプション | リアルタイム更新・型安全なAPI | JavaScript Resolver採用・Multi-auth設計・Enhanced Subscription Filtering |
5サービスの連携パターン例
| パターン | 構成 | ユースケース |
|---|---|---|
| 非同期注文処理 | API Gateway → SQS → Lambda | 注文受付のバックプレッシャー対応 |
| イベント駆動通知 | EventBridge → SNS → SQS/Lambda | マイクロサービス間の疎結合連携 |
| リアルタイムダッシュボード | AppSync Subscription + DynamoDB Streams | ライブデータ更新 |
| スケジュールバッチ | EventBridge Scheduler → SQS → Lambda | 定期バッチ処理のキュー管理 |
| APIオーケストレーション | API Gateway → Lambda → AppSync | REST/GraphQL統合エンドポイント |
Vol1 達成したこと:
– SQS: Standard/FIFO選定・DLQ設計・Visibility Timeout・Lambda統合・バッチ処理
– SNS: Fan-outパターン・サブスクリプションフィルタ・FIFO Topic・モバイル配信
– EventBridge: イベントバス設計・Scheduler・Pipes・Schema Registry・SaaS統合
– API Gateway: REST/HTTP API選定・認可統合・スロットリング・キャッシュ・カスタムドメイン
– AppSync: GraphQLスキーマ設計・リゾルバパイプライン・リアルタイムサブスクリプション・Merged API
5サービスを統合運用することで、疎結合・高可用・スケーラブルなAWSアーキテクチャを実現できる。
§8-2: 全軸クロスリンク
Application Integration Vol1は第25軸目として位置づけられる。既存の24軸と本記事の関連性を一覧にまとめる。
| 軸 | テーマ | 本記事との関連 | リンク |
|---|---|---|---|
| 第1軸 | VPC/ネットワーク基盤設計 | SQS/SNSのVPCエンドポイント設計の基盤 | 記事を読む |
| 第2軸 | ハイブリッド接続 (Direct Connect/VPN/TGW) | オンプレ→AWS間のEventBridgeイベント連携 | 記事を読む |
| 第3軸 | ネットワーク高度化 (TGW/PrivateLink/VPN) | API GatewayのVPCリンク・PrivateLink統合 | 記事を読む |
| 第4軸 | Network Vol3 (Cloud WAN/VPC Lattice) | AppSync/API GatewayのVPC Lattice統合 | 記事を読む |
| 第5軸 | データベース基盤 (RDS/Aurora/DynamoDB) | SQS/AppSyncのデータソースとしてのDynamoDB | 記事を読む |
| 第6軸 | データベースVol4 (Aurora DSQL/DynamoDB Strong) | AppSync + DynamoDB強整合性設計 | 記事を読む |
| 第7軸 | コンテナVol1 (ECS/Fargate) | SQS Consumerとしての Fargate タスク設計 | 記事を読む |
| 第8軸 | コンテナVol2 (EKS/ArgoCD/Kustomize) | EventBridge → EKS イベント駆動ジョブ実行 | 記事を読む |
| 第9軸 | サーバーレスVol1 (Lambda/API GW/Step Functions) | ★最関連: API GatewayとLambda統合の深堀り | 記事を読む |
| 第10軸 | サーバーレスVol2 (EventBridge/SQS/SNS/Kinesis) | ★最関連: イベント駆動視点での4サービス解説 | 記事を読む |
| 第11軸 | データ分析Vol1 (Athena/Glue/Redshift) | EventBridgeでのデータパイプライントリガー | 記事を読む |
| 第12軸 | データ分析Vol2 (Kinesis/MSK/QuickSight) | SNS/SQSからKinesisへのデータ連携 | 記事を読む |
| 第13軸 | セキュリティVol3 (IAM/KMS/Secrets Manager) | AppSync AWS_IAM認証・SQS暗号化 (KMS) | 記事を読む |
| 第14軸 | 可観測性Vol2 (X-Ray/OpenTelemetry/ADOT) | API Gateway/AppSyncのX-Rayトレーシング | 記事を読む |
| 第15軸 | コスト最適化Vol1 (Cost Explorer/Budgets) | SQS/SNS/EventBridgeのコスト可視化 | 記事を読む |
| 第16軸 | コスト最適化Vol2 (RI/Spot/Graviton) | AppSyncキャッシュによるコスト削減効果の計測 | 記事を読む |
| 第17軸 | DevOps/CI-CD Vol1 (CodePipeline/Build/Deploy) | EventBridgeによるCI-CDパイプライントリガー | 記事を読む |
| 第18軸 | DevOps/CI-CD Vol3 (CDK Pipelines/GitOps) | AppSync CDKによるInfrastructure as Code管理 | 記事を読む |
| 第19軸 | エッジ/CDN Vol1 (CloudFront/Lambda@Edge/Route53) | API Gatewayカスタムドメイン + CloudFront配置 | 記事を読む |
| 第20軸 | 管理/ガバナンスVol1 (Organizations/Control Tower) | マルチアカウントでのSNSクロスアカウント配信 | 記事を読む |
| 第21軸 | マイグレーションVol1 (DMS/MGN/Snow Family) | オンプレアプリのAPIをAPI Gatewayで段階移行 | 記事を読む |
| 第22軸 | IoT Vol1 (IoT Core/Greengrass/SiteWise) | IoT CoreからSNS/SQS/EventBridgeへのルーティング | 記事を読む |
| 第23軸 | ML/AI Vol3 (SageMaker MLOps/Feature Store) | EventBridgeによるMLパイプライントリガー | 記事を読む |
| 第24軸 | 生成AI/Bedrock (Agents/RAG/Knowledge Bases) | AppSync GraphQL + Bedrock Agents統合 | 記事を読む |
| 第25軸 | Application Integration Vol1(本記事) | SQS×SNS×EventBridge×API GW×AppSync統合プラットフォーム | 本記事 |
– 第9軸(サーバーレスVol1): API GatewayとLambda統合の深堀り — 本記事のAPI Gateway章と双方向で参照
– 第10軸(サーバーレスVol2): イベント駆動アーキテクチャ視点でSQS/SNS/EventBridgeを解説 — 補完関係
– 第5軸(データベース基盤): AppSyncのDynamoDBリゾルバを実装する際の基礎知識を提供
– 第13軸(セキュリティVol3): AppSyncのIAM認証・SQS/SNSのKMS暗号化の詳細を解説
§8-3: 次記事予告 + シリーズ展望
Application Integration Vol1は第25軸目として「統合プラットフォーム」視点で5サービスを体系化した。Vol1完成により、AWS本番運用の全軸体系が60記事に達し、主要なAWSサービス領域をほぼ網羅したことになる。
Application Integration Vol2 (予定) — 次のフロンティア
Vol1で基礎を固めた5サービスに対し、Vol2では以下の高度化トピックを扱う予定:
| トピック | 内容 |
|---|---|
| Amazon MQ | ActiveMQ/RabbitMQ対応のマネージドメッセージブローカー。オンプレメッセージングの移行先 |
| AWS AppFlow | SalesforceやGoogle Analytics等SaaSとS3/Redshiftのノーコードデータ転送 |
| Step Functions × SQS/SNS | Distributed Map + SQS/SNSを組み合わせた高スケールバッチオーケストレーション |
| EventBridge Pipes 高度活用 | フィルタ・エンリッチメント・SQS/Kinesis/DynamoDB Streamsとの統合パターン |
| AppSync Merged API 深堀り | マイクロサービスチームでの分散スキーマ管理・衝突解決・CI-CD統合 |
AWS本番運用 全25軸 達成
[基盤層] VPC × ネットワーク × ハイブリッド接続
[コンピューティング] コンテナ(ECS/EKS) × サーバーレス(Lambda)
[データ層] データベース × データ分析 × ML/AI × 生成AI
[統合層] Application Integration ← 第25軸 (本記事) ★NEW
[運用層] 可観測性 × セキュリティ × DevOps × コスト最適化 × ガバナンス
Vol1からVol2へ進む前に、全25軸のクロスリンクを通じて体系的な知識を深めてほしい。特にサーバーレスVol2(第10軸)はイベント駆動アーキテクチャの補完として必読だ。
§8-4: 読者アクションリスト — 明日から始める5ステップ
Step 1: 既存アーキテクチャの統合点を棚卸し(1〜2日)
– 現在のサービス間連携がREST同期呼び出しになっていないか確認
– 失敗時の再試行・タイムアウト設計が欠如している箇所を特定
– SQS/SNS/EventBridgeで非同期化できる候補を洗い出す
Step 2: SQS DLQを全キューに設定(半日)
– 既存SQSキューのRedrivePolicy未設定を確認
– maxReceiveCount=3 + DLQをペアで作成
– DLQのCloudWatchアラームを設定
Step 3: EventBridge Archiveを本番イベントバスに設定(半日)
– カスタムイベントバスにArchiveを追加(保存期間90日以上を推奨)
– 将来の障害復旧・デバッグ時のイベント再生に備える
Step 4: API GatewayステージスロットリングをTerraform/CDKで管理(1日)
– 現在の設定をコードで表現してバージョン管理
– 本番/ステージング/開発で異なるスロットリング値を環境変数で切り替え
Step 5: AppSync新規プロジェクトでJavaScript Resolverを採用(1日)
– VTLで書かれた既存リゾルバをJS Resolverに移行する候補を1つ選ぶ
– Unit → JavaScript → テスト → 本番適用のサイクルを確立
§8-5: 参考リンク + 次のステップへ
Application Integration Vol1 の理解をさらに深めるためのリソースと、次の記事への案内を示す。
Application Integration Vol1 完走おめでとうございます。 SQS・SNS・EventBridge・API Gateway・AppSyncの5サービスを統合プラットフォーム視点で学んだことで、AWSにおけるサービス間連携の全体像が掴めたはずだ。
次のステップは サーバーレスVol2(第10軸) でイベント駆動アーキテクチャをより深く学ぶか、データ分析Vol1(第11軸) でEventBridgeで駆動するデータパイプラインを構築してほしい。Application Integration Vol2(Amazon MQ/AppFlow/Step Functions高度化)も今後公開予定なので、シリーズを引き続き追ってほしい。
本番運用 最終チェックリスト
本番環境に投入する前に、以下のチェックリストで5サービスの設定を確認してほしい。
Amazon SQS チェックリスト
- [ ] 全キューにDLQ(Dead Letter Queue)を設定し、maxReceiveCountを適切に設定している
- [ ] VisibilityTimeoutをLambdaタイムアウトの6倍以上に設定している
- [ ] Long Polling(ReceiveMessageWaitTimeSeconds=20)を有効にしている
- [ ] FIFOキューのMessageGroupIdがユーザー/エンティティ単位で設計されている
- [ ] DLQのメッセージ滞留数にCloudWatchアラームを設定している
Amazon SNS チェックリスト
- [ ] サブスクリプションフィルタを設定している場合、Publisherが正しいMessageAttributesを付与している
- [ ] FIFO Topicを使用する場合、サブスクリプション先をSQS FIFOのみにしている
- [ ] クロスアカウント配信の場合、リソースポリシーを適切に設定している
- [ ] モバイルプッシュ通知のプラットフォームアプリケーションが有効期限内の証明書を使用している
Amazon EventBridge チェックリスト
- [ ] 本番カスタムイベントバスにArchiveを設定し、保存期間を30日以上にしている
- [ ] イベントパターンをAWSコンソールの「Test event pattern」で検証済み
- [ ] スケジュールルールのタイムゾーン設定が意図したものになっている
- [ ] Pipesでのエラー時の送信先(DLQ)を設定している
Amazon API Gateway チェックリスト
- [ ] ステージレベルのデフォルトスロットリング(rate/burst)を設定している
- [ ] 本番ステージでアクセスログを有効にしている
- [ ] カスタムドメインのSSL証明書が有効期限内
- [ ] 使用量プランとAPIキーを設定してクライアント別のレート制限を実装している
AWS AppSync チェックリスト
- [ ] プライマリ認証にAPI_KEY単独を使用していない(本番環境)
- [ ] CloudWatch Logsのフィールドログレベルを適切に設定している(本番:ERROR、開発:ALL)
- [ ] サブスクリプションを使用している場合、Enhanced Subscription Filteringを設定している
- [ ] キャッシュのTTL設定がデータの更新頻度に合っている
本記事でAWS Application Integration Vol1の全セクションを完走した。SQS・SNS・EventBridge・API Gateway・AppSyncの5サービスは、個々の理解だけでなく「組み合わせてシステムを設計する」視点が本番運用の核心だ。
詰まり7選とアンチパターン演習5問を自社の既存構成と照らし合わせ、改善できる点から一歩ずつ進めてほしい。Vol2の公開まで、全25軸のクロスリンクを活用して体系的な知識を深めることを勧める。