Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Amplify Gen2 Deep Dive / バックエンドの型をいかにしてフロントエンドへ...

Amplify Gen2 Deep Dive / バックエンドの型をいかにしてフロントエンドへ伝えるか #TSKaigi #TSKaigiKansai #AWSAmplifyJP

TSKaigi Kansai 2024 登壇資料。
https://kansai.tskaigi.org/talks/tacck

Kihara, Takuya

November 15, 2024
Tweet

More Decks by Kihara, Takuya

Other Decks in Technology

Transcript

  1. Amplify Gen2 Deep Dive バックエンドの型をいかにして フロントエンドへ伝えるか TSKaigi Kansai 2024 2024/11/16

    Kihara, Takuya (@tacck) TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep Dive 1
  2. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 2 Kihara, Takuya 木原 卓也 / @tacck / Sapporo, Japan CO-OP Sapporo 生活協同組合コープさっぽろ Software Engineer / Flutter, TypeScript, Vue.js, React Amplify Japan User Group 運営メンバー ゆるWeb勉強会@札幌 主催 AWS Community Builder Since Q2 2021 / Category: Front-end Web and Mobile Community 好きなフィギュアスケートの技 スプレッド・イーグル
  3. 今日のお話 ▪ Amplify Gen2 – AWS Amplify とは – Amplify

    Gen2 の開発者体験(DX)強化 – Sandbox – バックエンドとフロントエンド・リソースの連携 ▪ Deep Dive in Code – フィールド・モデル・スキーマの型 – フロントエンドへの型連携 – Sandbox での CDK 実行 TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep Dive 4
  4. AWS Amplify とは ▪ フロントエンドアプリケーションを開発するための、サービスおよびツール群。 – CI/CD を備えたホスティングサービス – Git

    branches をベースとしたデプロイ先の切り分け – AWS リソース(Cognito, S3, AppSync, etc) のためのライブラリ群 – Web フロントエンド用ライブラリ ▪ React / Next.js / Angular / Vue / JavaScript – スマートフォンアプリ用ライブラリ ▪ React Native / Flutter / Android / Swift ▪ mBaaS → フロントエンドホスティング強化 → フロントエンド開発者体験強化 TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep Dive 6
  5. 開発者体験 (Developer Experience) 強化 ▪ TypeScript での開発強化 – Web フロントエンドライブラリの

    TypeScript 対応 – バックエンドリソースの TypeScript での宣言 – Lambda Functions の TypeScript 実装対応 – etc... ▪ 開発中の Sandbox 機能追加 (開発環境をAWSへ即時反映) – Run CDK with hotswapping TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep Dive 7
  6. Sandbox とは TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify

    Gen2 Deep Dive 8 ▪ 開発者のマシンとAWSリソースを直接繋ぐ仕組み – バックエンドのリソースファイル保存に応じて、 即時でAWSへ環境構築。 – 複数人でも、それぞれ専用の環境が構築される。 – AWS CDK のホットスワッピングを使い、高速デプロイ。
  7. 今回の流れ ▪ ターゲット – Data リソース (amplify/data/resource.ts) ▪ フィールド・モデル・スキーマの型 ▪

    フロントエンドへの型連携 ▪ Sandbox での CDK 実行 TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep Dive 14
  8. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 16 “ModelField” がフィールドの型 amplify/data/resource.ts Fields
  9. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 17 resource.ts で string() をフィールドに設定。 ModelField.ts に string() の定義がある。 実際は _field() メソッドを返す。 node_modules/@aws-amplify/data-schema/src/ModelField.ts Fields
  10. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 18 _field() の中で、require() などの メソッドが定義されている。 メソッド自体の戻り値の型は “ModelField”。 node_modules/@aws-amplify/data-schema/src/ModelField.ts Fields
  11. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 19 ModelField 型の中で、チェインさせるメソッ ドの型定義。 require() は, “UsedMethod” と “required” のユニ オン型を使って自身を再度呼ぶ。 Omit によりメソッドチェインの制御。 node_modules/@aws-amplify/data-schema/src/ModelField.ts Fields
  12. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 20 model() メソッドは “ModelType” 型。 amplify/data/resource.ts Models
  13. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 21 resource.ts で model() を利用。 ModelType.ts に model() の定義がある。 実際は _model() メソッドを返す。 node_modules/@aws-amplify/data-schema/src/ModelType.ts Models
  14. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 22 _model() メソッドの戻り値の型は “ModelType”。 fields に、フィールドが格納される。 node_modules/@aws-amplify/data-schema/src/ModelType.ts Models
  15. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 23 ModelType 型の中で、チェインさせるメソッ ドのの型定義。 ModelField 型と同様に、チェインさせる メソッドは、 “UsedMethod” と Omit を使って 制御。 node_modules/@aws-amplify/data-schema/src/ModelType.ts Models
  16. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 24 schema() メソッドのは “ModelSchema” 型。 amplify/data/resource.ts Schema
  17. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 25 resource.ts で schema() メソッドを利用。 ModelSchema.ts に schema() メソッドの定義 がある。 実際は bindConfigToSchema() が呼ばれる。 node_modules/@aws-amplify/data-schema/src/ModelSchema.ts
  18. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 26 bindConfigToSchema() メソッドは “SchemaReturnType” 型を返す。 “SchemaReturnType” の実際の型は “ModelSchema” 型。 node_modules/@aws-amplify/data-schema/src/ModelSchema.ts Schema
  19. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 27 ”ModelSchema” 型の中で、チェインさせる メソッドの型定義。 “ModelField”と同様に、“UsedMethod” と Omit を使って制御。 node_modules/@aws-amplify/data-schema/src/ModelSchema.ts Schema
  20. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 28 bindConfigToSchema() を再度確認。 _ddbSchema() メソッドを呼び出している。 (DynamoDB利用の場合) node_modules/@aws-amplify/data-schema/src/ModelSchema.ts Schema
  21. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 29 schema() の返すオブジェクトの生成。 models フィールドの中に、 モデル(今回だと “Todo”)が格納される。 node_modules/@aws-amplify/data-schema/src/ModelSchema.ts Schema
  22. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 30 ModelSchema ModelType ModelField models: fields: string() integer() …
  23. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 32 フロントエンドからは Schema 型を使う。 これは、 “resource.ts” に定義。 “Todo” は、自分で宣言したモデル。 “type” はどこから? “ClientSchema” 型を確認。 amplify/data/resource.ts
  24. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 33 型引数 “Schema” は、先に見た通り “ModelSchema” 型。 “ModelSchema” と “GenericModelSchema” は 要素が同じになるため、実際の型として “InternalClientSchema” が選択される。 node_modules/@aws-amplify/data-schema/src/ClientSchema/index.ts
  25. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 34 “InternalClientSchema” の型引数 “CustomerSchema” は “ModelSchema”。 そして、“ModelSchemaContents” でもある。 そのため、プロパティの型として “ClientSchemaProperty” を選択。. node_modules/@aws-amplify/data-schema/src/ClientSchema/index.ts
  26. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 35 型引数 “T” は “ModelSchema”。 つまり “T[K]” スキーマの持つ要素になるので、 “ModelType” となる。 そのため、 “RemapModel” 型が選択される。 node_modules/@aws-amplify/data-schema/src/ClientSchema/index.ts
  27. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 36 型引数 “E” が “ModelType” として 呼ばれている。 そのため、 “ClientModel” 型が選ばれる。 node_modules/@aws-amplify/data-schema/src/ClientSchema/index.ts
  28. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 37 “ClientModel” 型の中に、最初にフロントエン ドで使っていた “type” プロパティが出てきた。 値の型は、 “ClientFields” 型であり、 さらに中を見ると “ResolveFields” 型。 node_modules/@aws-amplify/data-schema/src/ClientSchema/Core/ClientModel.ts
  29. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 38 “ResolveFields” 型で、プロパティの名前と 値のチェック。 ここは、Nullableでもそうでなくても同じ型 “ResolveIndividualField” が使われる。 node_modules/@aws-amplify/data-schema/src/ClientSchema/utilities/ResolveField.ts
  30. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 39 “ResolveIndividualField” の中で、型引数 “T” が “BaseModelField” 型かの確認。 これは、フィールドの値として呼ばれている ので、 “ModelField” 型であるはず。 node_modules/@aws-amplify/data-schema/src/ClientSchema/utilities/ResolveField.ts
  31. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 40 “BaseModelField” 型の中を見ると、 “ModelField” 型が実体となっている。 node_modules/@aws-amplify/data-schema/src/ModelField.ts
  32. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 41 “type” の中に、 “ModelField” が連携される。 →タイプ・ヒンティングで 宣言内容が出てくる。 amplify/data/resource.ts
  33. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 43 “ampx” コマンドは “yargs” パッケージを利用。 引数の解釈・実行はそれに準じている。 まずは “createMainParser” メソッドの確認。 packages/cli/src/ampx.ts
  34. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 44 Sandbox のコマンド定義のみ取り上げる。 “createSandboxCommand” メソッド確認。 packages/cli/src/main_parser_factory.ts
  35. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 45 コードのポイントが二つ。 yargs のための “コマンド実行の定義” と “CDK 実行の定義”。 packages/cli/src/commands/sandbox/sandbox_command_factory.ts
  36. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 46 “SandboxSingletonFactory” が “CDK 実行の定義”。 packages/cli/src/commands/sandbox/sandbox_command_factory.ts
  37. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 47 “SandboxCommand” が “コマンド実行の定義”。 まずはこちらから。 packages/cli/src/commands/sandbox/sandbox_command_factory.ts
  38. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 48 “SandboxCommand” は “yargs” のための定義。 呼び出し時のコマンド “npx ampx sandbox” の 引数 “sandbox” が “this.command = ‘sandbox‘“ に一致するとこのオブジェクトが 実行される。 packages/cli/src/commands/sandbox/sandbox_command.ts
  39. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 49 “yargs” が “handler” メソッドを呼び出す。 “handler” の中で “sandbox.start()” をさらに呼び出し。 “sandbox” はコンストラクタの第一引数。 packages/cli/src/commands/sandbox/sandbox_command.ts
  40. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 50 “createSandboxCommand” を再確認。 第一引数の “sandboxFacory” は “SandboxSingletonFactory”。 二つ目のポイントの “CDK 実行の定義”。 packages/cli/src/commands/sandbox/sandbox_command_factory.ts
  41. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 51 “SandboxSingletonFactory” の処理の実体は “getInstance()” メソッド。 その中で “FileWatchingSandbox” を 呼んでいる。 packages/sandbox/src/sandbox_singleton_factory.ts
  42. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 52 “FileWatchingSandbox” の中の “start” メソッ ドが、 “SandboxCommand” の中で呼んでい た “sandbox.start()” の実体。 packages/sandbox/src/file_watching_sandbox.ts
  43. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 53 “start()” メソッドを追うと、内部で “deployAndWatch()” を呼んでいる。 packages/sandbox/src/file_watching_sandbox.ts
  44. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 54 “deployAndWatch()” メソッドは、 さらに “this.deploy()” メソッドを呼ぶ。 packages/sandbox/src/file_watching_sandbox.ts
  45. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 55 “this.deploy()” メソッドは、さらに “this.executor.deploy()” メソッドを呼ぶ。 packages/sandbox/src/file_watching_sandbox.ts
  46. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 56 “this.executor” は “FileWatchingSandbox” の 第二引数。 packages/sandbox/src/file_watching_sandbox.ts
  47. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 57 “SandboxSingletonFactory” で引数の確認。 第二引数は “AmplifySandboxExecutor” クラス。 packages/sandbox/src/sandbox_singleton_factory.ts
  48. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 58 packages/sandbox/src/sandbox_executor.ts “AmplifySandboxExecutor” の “deploy()” メソッドが、 “FileWatchingSandbox” の “this.executor.deploy()” として呼ばれている。 その中で、 “this.backendDeployer.deploy()” を呼んでいる。
  49. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 59 packages/sandbox/src/sandbox_executor.ts “this.backendDeployer” は コンストラクタの第一引数。
  50. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 60 “SandboxSingletonFactory” で引数の確認。 “AmplifySandboxExecutor” の第一引数は、 “BackendDeployerFactory” クラス。 packages/sandbox/src/sandbox_singleton_factory.ts
  51. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 61 packages/backend-deployer/src/cdk_deployer_singleton_factory.ts “BackendDeployerFactory” の実際の処理は “getInstance()” メソッド。 この中で “CDKDeployer” クラスを呼んでいる。
  52. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 62 packages/backend-deployer/src/cdk_deployer.ts “CDKDeployer” クラスの “deploy()” メソッドが、 “AmplifySandboxExecutor” の “this.backendDeployer.deploy()” として 呼ばれる。
  53. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 63 packages/backend-deployer/src/cdk_deployer.ts この “deploy()” メソッドの処理を追うと、 さ らに “this.tryInvokeCdk()” を呼んでいる。
  54. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 64 packages/backend-deployer/src/cdk_deployer.ts “this.tryInvokeCdk()” メソッドを追うと、 さらに “this.invokeCdk()” メソッドを 呼んでいる。
  55. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 65 packages/backend-deployer/src/cdk_deployer.ts “this.invokeCdk” メソッドを追うと、 “this.executeCommand()” を呼んでいる。
  56. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 66 packages/backend-deployer/src/cdk_deployer.ts そして、 “this.executeCommand” メソッドを 確認すると、 “this.packageManagerController.runWithPacka geManager()” メソッドを呼んでいる。
  57. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 67 packages/backend-deployer/src/cdk_deployer.ts “this.packageManagerController” は、 “CDKDeployer” のコンストラクタの第三引数。
  58. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 68 packages/backend-deployer/src/cdk_deployer_singleton_factory.ts “BackendDeployerFactory” に戻って確認。 “CDKDeployer“ の第三引数は、 ベースクラスのコンストラクタの第一引数. “packageManagerController”。
  59. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 69 さらに “SandboxSingletonFactory” へ 戻って確認。 “BackendDeployerFactory“ の第一引数は “PackageManagerControllerFactory” クラス。 packages/sandbox/src/sandbox_singleton_factory.ts
  60. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 70 packages/cli-core/src/package-manager-controller/package_manager_controller_factory.ts “PackageManagerControllerFactory” クラスの処理 の実体は “getPackageManagerController()” メソッド。 ここではパッケージマネージャーに “NPM” を使う 前提で “NpmPackageMnagerController” を確認。
  61. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 71 packages/cli-core/src/package-manager-controller/npm_package_manager_controller.ts “NpmPackageManagerController” はコンスト ラクタで super() を呼ぶだけ。 親クラスの “PackageManagerControllerBase” を続けて確認。
  62. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 72 packages/cli-core/src/package-manager-controller/package_manager_controller_base.ts “PackageManagerControllerBase” の中で、 “CDKDeployer” で呼んでいた “runWithPackageManager” を発見。 さらに、 “this. executeWithDebugLogger” が 呼ばれている。
  63. TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep

    Dive 73 packages/cli-core/src/package-manager-controller/execute_with_debugger_logger.ts 最終的に、 “execa” パッケージを使った 処理を発見。 ここでコマンドとしての “CDK” を実行。
  64. まとめ ▪ バックグラウンドのリソースファイル(i.e. “amplify/data/resource.ts”) が、 フロントエンドの型として連携されることの確認。 – TypeScript の型定義を駆使してできている。 ▪

    ampx コマンド経由で Sandbox を有効にし、 リソースファイルの更新に応じてAWS CDKコマンドを実行していることを確認。 ▪ これらの仕組みがによって、AWS Amplifyでの開発者体験が 格段に向上した。 TSKaigi Kansai 2024 / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep Dive 75
  65. Amplify Japan User Group AWS Amplify に関する情報発信・ミートアップを開催 TSKaigi Kansai 2024

    / #TSKaigi #TSKaigiKansai / Amplify Gen2 Deep Dive 77 Disocrd はこちらから参加!! https://aws-amplify-jp.github.io/
  66. Amplify Boostup #7 2024/12/19 東京+オンライン TSKaigi Kansai 2024 / #TSKaigi

    #TSKaigiKansai / Amplify Gen2 Deep Dive 78 https://aws-amplify-jp.connpass.com/event/334686/