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
Organize your chaotic DynamoDB (with Node.js) /...
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
osamu.arita
May 11, 2021
Programming
910
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Organize your chaotic DynamoDB (with Node.js) / Organize your chaotic DynamoDB with Nodejs
osamu.arita
May 11, 2021
More Decks by osamu.arita
See All by osamu.arita
LocalStackを利用した単体テストのすすめ / First Steps in Unit Testing using LocalStack
osamu_arita
1
1.2k
Flutter初心者が アニメーションを試してみる/try-flutter-animation
osamu_arita
2
2.1k
Other Decks in Programming
See All in Programming
GitHub Copilot CLIのいいところ
htkym
2
1.3k
AIとRubyの静的型付け
ukin0k0
0
550
CSC307 Lecture 17
javiergs
PRO
0
320
「AIで開発し、AIを届ける」をEvalでつなぐ 〜AIネイティブに始めるプロダクト開発の実践〜 / Connecting "Develop with AI, deliver AI" with Eval
rkaga
4
4.7k
The Arts and Crafts of Work in the AI Era — Toward Mastery in Software Development
kuranuki
1
730
Dataformのリポジトリを立ち上げるときにまずやること / dataform-day0-2026
snhryt
0
120
決定論的オーケストレーションの設計と実装 / Design and Implementation of Deterministic Orchestration
nrslib
3
1.2k
JJUG CCC 2026 Spring: JSpecify で実現する Kotlin フレンドリーな Java API 設計
ternbusty
1
150
Lessons from Spec-Driven Development
simas
PRO
0
150
Copilot CLI の継戦能力を高める コンテキスト管理
nozomutu
1
1.2k
「エンジニアインターン、どうやって取った?」準備のリアルを語るLT会 Progate BAR
akiomatic
0
120
RTSPクライアントを自作してみた話
simotin13
0
510
Featured
See All Featured
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
360
The untapped power of vector embeddings
frankvandijk
2
1.7k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
10k
Building an army of robots
kneath
306
46k
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
220
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
390
AI: The stuff that nobody shows you
jnunemaker
PRO
8
690
Designing for humans not robots
tammielis
254
26k
We Have a Design System, Now What?
morganepeng
55
8.2k
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
240
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
201
75k
Automating Front-end Workflow
addyosmani
1370
210k
Transcript
Organize your chaotic DynamoDB (with Node.js) osamu.arita - LINE Fukuoka
GWの自由研究発表会 - 11st/May/2021
ABOUT ME • LINE Fukuokaのエンジニア ◦ 以前はiOSエンジニアをしていました ◦ 今は「LINE SMART
CITY GovTech プログラム」の開発サポート全般 • 社会人歴15年 / 社歴1年目 ◦ AWS / Firebase / Ruby on Rails / PHP(Laravel、etc..) ◦ iOS(swift)/ Android(Kotlin / Java)/ Flutter(Dart) • GWは、息子(現5歳)と遊ぶのが中心でした • slack - #z_osamu osamu_arita osamu.arita
GWにやったこと
Organize your chaotic DynamoDB (with Node.js)
カオスなDynamoDBを整理する (with Node.js)
DynamoDBとは • フルマネージド型NoSQLデータベース ◦ プライマリーキー以外はスキーマレス ◦ key-value (wide-column store) およびドキュメントデータモデルをサポート
• 高可用性:3つのAZ(Availability Zone)でレプリケーションを持っている
RDBMSとNoSQLの比較 RDBMS(RDS) NoSQL(DynamoDB) スキーマ (テーブル定義) スキーマあり プライマリーキー以外はスキーマレス
拡張性 - 高 トランザクション ACID特性 ・原子性 (Atomicity) ・一貫性 (Consistency) ・独立性 (Isolation) ・永続性 (Durability) BASE特性 ・基本的に利用可能 (Basically Available) ・厳密ではない状態遷移 (Soft state) ・結果整合性 (Eventual consistency) 【備考】 ・ConsistentRead(強い整合性のある読み込み)パラメータ あり ・DynamoDB Transactions API:リージョン内でACIDを保 証 操作 SQL ・Classic API ・PartiQL(パーティクル) - SQL互換の クエリ言語
DynamoDBのテーブル要素 Partition Key Sort Key Attribute Item Attribute Attribute Attribute
Schema定義 他に Secondary Index もあります LSI - Sort Key以外で絞り込み。テーブル作成時に定義 GSI - Partition Keyを別途設定。後で追加可能。但しコスト大
DynamoDBのテーブル要素 Partition Key Sort Key Attribute Item Attribute Attribute Attribute
Schema定義 プログラムなどで動的に追加
とあるプロジェクトの構成 エンジニアAさん リポジトリ エンジニアBさん GitHub commit & push commit &
push deploy (AWS CloudFormation, AWS SAM) pull pull AWS(Serverless構成) DynamoDB AWS Lambda API Gawatey Node.js table A table B ※フロントエンドなど細かい部分は省略
とあるプロジェクトの構成 エンジニアAさん リポジトリ エンジニアBさん GitHub commit & push commit &
push deploy (AWS CloudFormation, AWS SAM) pull pull AWS(Serverless構成) DynamoDB AWS Lambda API Gawatey Node.js table A table B ※フロントエンドなど細かい部分は省略 ファイルA:table A に「updateAt」追加 ファイルB:table A に「memo」追加
とあるプロジェクトの構成 エンジニアAさん リポジトリ エンジニアBさん GitHub commit & push commit &
push deploy (AWS CloudFormation, AWS SAM) pull pull AWS(Serverless構成) DynamoDB AWS Lambda API Gawatey Node.js table A table B ※フロントエンドなど細かい部分は省略 エンジニアCさん参加
とあるプロジェクトの構成 エンジニアAさん リポジトリ エンジニアBさん GitHub commit & push commit &
push deploy (AWS CloudFormation, AWS SAM) pull pull AWS(Serverless構成) DynamoDB AWS Lambda API Gawatey Node.js table A table B ※フロントエンドなど細かい部分は省略 エンジニアCさん tableの構成がソースコード上でバラついて 全然わからない!
Table定義を集約しよう
DynamoDB操作 - Node.JS • AWS SDK for JavaScriptで提供されているライブラリ ◦
v2 ◦ v3 ◦ 参考 ▪ https://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v2/developer-guide/dynamodb-example-document-client.html ▪ https://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v3/developer-guide/welcome.html const {DynamoDB} = require("@aws-sdk/client-dynamodb" ); const { DynamoDBClient, ListTablesCommand }= require('@aws-sdk/client-dynamodb' ); // Commandベースでテーブル一覧取得やテーブル操作など const dbclient = new DynamoDBClient({ region: 'us-west-2' }); var AWS = require('aws-sdk'); AWS.config.update( {region: 'REGION'}); // テーブル一覧取得など var ddb = new AWS.DynamoDB({apiVersion: "2006-03-01" }); // テーブル操作 var docClient = new AWS.DynamoDB. DocumentClient({apiVersion: '2012-08-10' });
DynamoDB操作 - Node.JS • AWS SDK for JavaScriptで提供されているライブラリ ◦
v2 ◦ v3 ◦ 参考 ▪ https://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v2/developer-guide/dynamodb-example-document-client.html ▪ https://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v3/developer-guide/welcome.html const {DynamoDB} = require("@aws-sdk/client-dynamodb" ); const { DynamoDBClient, ListTablesCommand }= require('@aws-sdk/client-dynamodb' ); // Commandベースでテーブル一覧取得やテーブル操作など const dbclient = new DynamoDBClient({ region: 'us-west-2' }); var AWS = require('aws-sdk'); AWS.config.update( {region: 'REGION'}); // テーブル一覧取得など var ddb = new AWS.DynamoDB({apiVersion: "2006-03-01" }); // テーブル操作 var docClient = new AWS.DynamoDB. DocumentClient({apiVersion: '2012-08-10' }); v3のメリット ・SDKがTypeScriptで記述されている ・サービスごとに個別のパッケージが利用可能 ・新しいmiddlewareStack など
DynamoDB Table定義集約 - Node.JS • Amazon DynamoDB DataMapper For JavaScript
◦ awslabsが提供しているライブラリ ◦ modelを作成することでTable定義を集約できる ◦ 参考 ▪ https://github.com/awslabs/dynamodb-data-mapper-js ▪ https://awslabs.github.io/dynamodb-data-mapper-js/packages/dynamodb-data-mapper/ @table('table_name') class MyDomainObject { @hashKey() id: string; @rangeKey({defaultProvider: () => new Date()}) createdAt: Date; @attribute() completed?: boolean; }
DynamoDB Table定義集約 - Node.JS • Amazon DynamoDB DataMapper For JavaScript
◦ awslabsが提供しているライブラリ ◦ modelを作成することでTable定義を集約できる ◦ 参考 ▪ https://github.com/awslabs/dynamodb-data-mapper-js ▪ https://awslabs.github.io/dynamodb-data-mapper-js/packages/dynamodb-data-mapper/ @table('table_name') class MyDomainObject { @hashKey() id: string; @rangeKey({defaultProvider: () => new Date()}) createdAt: Date; @attribute() completed?: boolean; } コードとしてはv2に対応
DynamoDB Table定義集約 - Node.JS • Amazon DynamoDB DataMapper For JavaScript
◦ awslabsが提供しているライブラリ ◦ modelを作成することでTable定義を集約できる ◦ 参考 ▪ https://github.com/awslabs/dynamodb-data-mapper-js ▪ https://awslabs.github.io/dynamodb-data-mapper-js/packages/dynamodb-data-mapper/ @table('table_name') class MyDomainObject { @hashKey() id: string; @rangeKey({defaultProvider: () => new Date()}) createdAt: Date; @attribute() completed?: boolean; } dynamodb-data-mapper-annotations を利用すると 左記のようにきれいに書けるけれど、 JavaScriptで記載する場合は以下の通り class MyDomainObject { } Object.defineProperties(MyDomainObject.prototype, { [DynamoDbTable]: { value: 'table_name' }, [DynamoDbSchema]: { value: { id: { type: 'String', keyType: 'HASH' }, foo: { type: 'String', keyType: 'RANGE' }, : }, }, });
DynamoDB Table定義集約 - Node.JS • Amazon DynamoDB DataMapper For JavaScript
◦ awslabsが提供しているライブラリ ◦ modelを作成することでTable定義を集約できる ◦ 参考 ▪ https://github.com/awslabs/dynamodb-data-mapper-js ▪ https://awslabs.github.io/dynamodb-data-mapper-js/packages/dynamodb-data-mapper/ @table('table_name') class MyDomainObject { @hashKey() id: string; @rangeKey({defaultProvider: () => new Date()}) createdAt: Date; @attribute() completed?: boolean; } dynamodb-data-mapper-annotationsを利用する場合 tsconfig.jsonで experimentalDecorators と emitDecoratorMetadata オプションを true にする必要あり tsconfig.json { "compilerOptions": { "experimentalDecorators ": true, "emitDecoratorMetadata ": true, }
DocumentClient(v2)とDataMapperの比較 (1) DocumentClient(v2) DataMapper scan scan(params, callback) ⇒
AWS.Request scan<T extends StringToAnyObjectMap>( valueConstructor: ZeroArgumentsConstructor<T>, options?: ScanOptions|ParallelScanWorkerOptions ): ScanIterator<T>; get get(params, callback) ⇒ AWS.Request get<T extends StringToAnyObjectMap = StringToAnyObjectMap>( item: T, options?: GetOptions ): Promise<T>; put put(params, callback) ⇒ AWS.Request put<T extends StringToAnyObjectMap = StringToAnyObjectMap>( item: T, options?: PutOptions ): Promise<T>; 一通りのメソッドは用意されている。scanは戻り値の型がPromiseではないので注意
DocumentClient(v2)とDataMapperの比較 (2) DocumentClient(v2) DataMapper update update(params, callback) ⇒
AWS.Request update<T extends StringToAnyObjectMap = StringToAnyObjectMap>( item: T, options?: UpdateOptions ): Promise<T>; delete delete(params, callback) ⇒ AWS.Request delete<T extends StringToAnyObjectMap = StringToAnyObjectMap>( item: T, options?: DeleteOptions ): Promise<T|undefined>; • 参考 ◦ https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/DocumentClient.html ◦ https://awslabs.github.io/dynamodb-data-mapper-js/packages/dynamodb-data-mapper/ ◦ https://github.com/awslabs/dynamodb-data-mapper-js/blob/master/packages/dynamodb-data-mapper/src/DataMapper.ts 一通りのメソッドは用意されている
試してみよう
試してみた構成 エンジニアAさん ・言語:TypeScript(※1) ・DynamoDB:create-table / put-item ・AWS Lambda:create-function
/ delete-function / invoke (※1)dynamodb-data-mapperのサンプルがTypeScriptベース localstack DynamoDB AWS Lambda Node.js テーブル: SurveyResults • 参考 ◦ https://github.com/localstack/localstack ◦ https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/workbench.settingup.html ・AWS提供のNoSQL Workbenchで実際のデータ確認
試してみた構成 エンジニアAさん ・言語:TypeScript(※1) ・DynamoDB:create-table / put-item ・AWS Lambda:create-function
/ delete-function / invoke (※1)dynamodb-data-mapperのサンプルがTypeScriptベース localstack DynamoDB AWS Lambda Node.js テーブル: SurveyResults • 参考 ◦ https://github.com/localstack/localstack ◦ https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/workbench.settingup.html ・AWS提供のNoSQL Workbenchで実際のデータ確認 ・サービス共通で http://localhost:4566/ にてアクセス可能 ・localstack内でアクセスする場合、 http://${process.env.LOCALSTACK_HOSTNAME}:4566 とLOCALSTACK_HOSTNAMEを利用することでアクセス可能
今回作成したリポジトリ https://github.com/noeloasis/localstack-dynamodb 必要に応じて「-g」を「-D」にしてください 事前準備。記載されているコマンドを実行します localstackに接続するためのAWS profileを作成します Access Key,
Secret Access Keyの値は何でも良いですが コード内で指定しているため、このまま入力します
今回作成したリポジトリ Dockerは事前にインストールしてください healthイメージ localstackを別のディレクトリにcloneして起動(up)します localstackを停止(down)する場合は次のコマンドを実行します
今回作成したリポジトリ https://github.com/noeloasis/localstack-dynamodb setup →「SurveyResults」テーブル作成+1件item登録 update_lambda_01 → DocumentClient(v2)サンプルのLambda作成 update_lambda_02 → DataMapperサンプルのLambda作成 run_lambda_01 → DocumentClient(v2)サンプルのLambda実行 run_lambda_02 → DataMapperサンプルのLambda実行 list_lambda → 登録されているLambdaのリストを表示
今回作成したリポジトリ https://github.com/noeloasis/localstack-dynamodb 記載されている通りに設定してください
今回作成したリポジトリ https://github.com/noeloasis/localstack-dynamodb NoSQL Workbenchのイメージ 「./bin/setup」を実行した直後です 「SurveyResults」テーブル作成+1件
item登録されています
demo
とあるプロジェクトの構成 エンジニアAさん リポジトリ エンジニアBさん GitHub commit & push commit &
push deploy (AWS CloudFormation, AWS SAM) pull pull AWS(Serverless構成) DynamoDB AWS Lambda API Gawatey Node.js table A table B ※フロントエンドなど細かい部分は省略 エンジニアCさん tableの構成がソースコード上でバラついて 全然わからない!
とあるプロジェクトの構成 エンジニアAさん リポジトリ エンジニアBさん GitHub commit & push commit &
push deploy (AWS CloudFormation, AWS SAM) pull pull AWS(Serverless構成) DynamoDB AWS Lambda API Gawatey Node.js table A table B ※フロントエンドなど細かい部分は省略 エンジニアCさん tableの構成がソースコード上で わかる(わかりそう)!
まとめ • カオスなDynamoDB ◦ 複数のエンジニアが開発を行い、table情報がソースコード上でばらついている状態 • DataMapperを利用する事で、モデルとして整理できそう ◦ ただし・・
▪ scanの戻り値の型がScanIteratorでPromiseと異なるので注意 ▪ AWS SDK for JavaScript (v3) を利用したい場合は、別の方法を検討 • DynamoDBを試したい場合、localstack+NoSQL Workbenchは便利!
Thank You ! ご清聴ありがとうございました!