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

Avatar for Kihara, Takuya

Kihara, Takuya

November 16, 2024
Tweet

Video

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/