Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
AWS SDKのClientはFactory経由で作ろう
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
TomoyaIwata
September 26, 2023
Programming
1
1k
AWS SDKのClientは Factory経由で作ろう
「緊急開催!サーバーレス座談会 in JAWS-UG 大阪」にてLTさせて頂いた際の資料です
https://jawsugosaka.doorkeeper.jp/events/162714
TomoyaIwata
September 26, 2023
Tweet
Share
More Decks by TomoyaIwata
See All by TomoyaIwata
Lambdaの常識はどう変わる?!re:Invent 2025 before after
iwatatomoya
1
1k
Aurora DSQLはサーバーレスアーキテクチャの常識を変えるのか
iwatatomoya
1
2.1k
これでLambdaが不要に?!Step FunctionsのJSONata対応について
iwatatomoya
2
6.3k
Qdrantでベクトルデータベースに入門してみよう
iwatatomoya
0
2k
詳解 AWS Lambdaコールドスタート
iwatatomoya
2
3.2k
真のサーバーレスへ向けたAuroraの進化Aurora Limitless Database
iwatatomoya
1
5k
OpentelemetryでアプリケーションのObservabilityを強化しよう
iwatatomoya
0
1.3k
AWS Lambdaは俺が作った
iwatatomoya
2
3.1k
SnapStartの未来についての期待と妄想
iwatatomoya
1
1.5k
Other Decks in Programming
See All in Programming
Fundamentals of Software Engineering In the Age of AI
therealdanvega
1
220
ふつうの Rubyist、ちいさなデバイス、大きな一年
bash0c7
0
720
Codex の「自走力」を高める
yorifuji
0
1k
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
310
AI時代のソフトウェア開発でも「人が仕様を書く」から始めよう-医療IT現場での実践とこれから
koukimiura
0
140
Go Conference mini in Sendai 2026 : Goに新機能を提案し実装されるまでのフロー徹底解説
yamatoya
0
540
今更考える「単一責任原則」 / Thinking about the Single Responsibility Principle
tooppoo
3
1.6k
エンジニアの「手元の自動化」を加速するn8n 2026.02.27
symy2co
0
110
NOT A HOTEL - 建築や人と融合し、自由を創り出すソフトウェア
not_a_hokuts
2
840
社内規程RAGの精度を73.3% → 100%に改善した話
oharu121
13
7.8k
Takumiから考えるSecurity_Maturity_Model.pdf
gessy0129
1
130
AIとペアプロして処理時間を97%削減した話 #pyconshizu
kashewnuts
1
210
Featured
See All Featured
KATA
mclloyd
PRO
35
15k
Rails Girls Zürich Keynote
gr2m
96
14k
A Modern Web Designer's Workflow
chriscoyier
698
190k
For a Future-Friendly Web
brad_frost
183
10k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
55k
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
310
The agentic SEO stack - context over prompts
schlessera
0
680
Information Architects: The Missing Link in Design Systems
soysaucechin
0
820
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
sira's awesome portfolio website redesign presentation
elsirapls
0
190
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
460
Build your cross-platform service in a week with App Engine
jlugia
234
18k
Transcript
AWS SDKのClientは Factory経由で作ろう クラスメソッド株式会社 岩⽥ 智哉 1
2 ⾃⼰紹介 l クラスメソッド株式会社 サーバーサイドエンジニア l 2023 Japan AWS Top
Engineer l 2023 Japan AWS All Certifications Engineer l 前⼗字靭帯再建⼿術リハビリ中 岩⽥ 智哉
3 ⾔いたいこと AWS SDKのClientは Factory経由で作ろう
4 LambdaとEC2/ECSの違い リクエストとコンピューティング環境がN:1 リクエストとコンピューティング環境が1:1
5 リクエストとコンピューティング環境が1:1だと… ソケット ソケット ソケット ソケット DynamoDB等のAWSサービス ソケット ソケット Lambda実⾏環境で⽣成するソケットは1つで⼗分
(なことが多い)
6 これらを意識すると AWS SDKのClientの扱いが 最適化できる
7 良くない例1 import boto3 class TableA: def __init__(self): self._client =
boto3.client('dynamodb') def put_item(self, item): self._client.put_item(TableName='tableA', Item=item) class TableB: def __init__(self, client): self._client = boto3.client('dynamodb') def put_item(self, item): self._client.put_item(TableName='tableB', Item=item) def handler(event, context): table_a = TableA() table_a.put_item({'foo': 'bar’}) table_b = TableB() table_b.put_item({'hoge': 'fuga'})
8 何が良くないのか︖
9 よくある解決策 class TableA: def __init__(self, client): self._client = client
def put_item(self, item): self._client.put_item(TableName='tableA', Item=item) class TableB: def __init__(self, client): self._client = client def put_item(self, item): self._client.put_item(TableName='tableB', Item=item) import boto3 client = boto3.client('dynamodb’) def handler(event, context): table_a = TableA(client) table_a.put_item({'foo': 'bar'}) table_b = TableB(client) table_b.put_item({'hoge': 'fuga'})
10 そうはいっても • 現実世界のアプリはもっと複雑。呼び出し階層も深くなる • 呼び出し先の呼び出し先の呼び出し先…にclientを伝搬するのは⾯倒 • clientの処理化処理はもっと⾊々やることがある import boto3
client = boto3.client('dynamodb’) def handler(event, context): table_a = TableA(client) table_a.put_item({'foo': 'bar'}) table_b = TableB(client) table_b.put_item({'hoge': 'fuga'})
11 提案 Factoryクラスを使おう︕
12 実装例(簡易版) import boto3 class Boto3ClientFactory: # ⽣成したclientクラスのインスタンスをクラス変数に保持しておく _clients =
{} @classmethod def get_singleton_client(cls, service_name, **kwargs): # 対象サービスのclientクラスを⽣成済みならクラス変数のキャッシュから返却 # 複数リージョンを扱う場合はキャッシュキーにリージョンを含めるなど追加の考慮が必要 if service_name in cls._clients: return cls._clients[service_name] client = boto3.client(service_name, **kwargs) cls._clients[service_name] = client return client
13 Factoryクラスの追加実装例 • タイムアウト値の調整 • デフォルト値はLambda実⾏環境の設定値としては不適切 • connect_timeout:60, read_timeout:60 •
Event Systemを利⽤したフックの登録 • API呼び出し前にパラメータをクラス変数に保存 • 例外キャッチ時にクラス変数に保存したパラメータをログ出⼒ • ⾮シングルトンなclientクラス⽣成処理 • たまにはPromise.All的な実装が必要になることもある
14 Factoryクラスの利⽤例 client = Boto3ClientFactory.get_singleton_client('dynamodb') def handler(event, context): table_a =
TableA(client) table_a.put_item({'foo': 'bar'}) table_b = TableB(client) table_b.put_item({'hoge': 'fuga'}) def foo(): bar() def bar(): baz() def baz(): client = Boto3ClientFactory.get_singleton_client('dynamodb') table_a = TableA(client) table_a.put_item({'foo': 'bar'}) def handler(event, context): foo() タイムアウト値など適切に設定された clientクラスが1発で取得可能 呼び出し階層の深いところまでclientクラ スを引き回さなくて良くなる
15 Provisioned Concurrency利⽤時の注意 Boto3ClientFactory.get_singleton_client('dynamodb’) def handler(event, context): … Init処理の中でclientクラスの⽣成を「空打ち」しておく
16 初回のClientクラス⽣成処理は重い https://github.com/boto/botocore/blob/40d6219947f4d047088cbeb80f8f222f599f9c7c/botocore/loaders.py • 初回のclientクラス⽣成時はJSONファイルを読み込んで動的にクラスを⽣成するので「重い」 • 2回⽬以後はキャッシュを使う • Init処理の中でclientクラス向けのキャッシュを「暖気」することでProvisioned Concurrencyに最適化
https://github.com/boto/botocore/blob/40d6219947f4d047088cbeb80f8f222f599f9c7c/botocore/data/dynamo db/2012-08-10/service-2.json
17 以上 ありがとうございました
18