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

Serverpodを活用したDartのフルスタックアプリケーション開発

Avatar for CyberAgent CyberAgent
March 21, 2024
730

 Serverpodを活用したDartのフルスタックアプリケーション開発

Dartでフルスタックにアプリケーション開発ができるServerpodの機能や実装方法について

Avatar for CyberAgent

CyberAgent

March 21, 2024
Tweet

More Decks by CyberAgent

Transcript

  1. Serverpodの使用方法 Serverpodの使用方法 1. Serverpod cli のインストール 2. Serverpod プロジェクトの作成 $

    dart pub global activate serverpod_cli $ serverpod create mypod mypod_server mypod_client mypod_flutter パッケージ が⽣成される
  2. 3. Serverpodの実行 • アプリケーションサーバー ◦ Flutterアプリがアクセスするためのサーバー • Serverpod insights サーバー

    ◦ サーバーの状態やログを確認するアプリケーションのためのサーバー • WEBサーバー ◦ アプリケーションサーバーにアクセス可能なWEBページやAPIを設定可能なサーバー ▪ まだ実験段階のため、API等が大きく変更される可能性あり Serverpodの使用方法 $ cd mypod/mypod_server $ docker compose up --build --detach $ dart bin/main.dart Local DB(Postgres), Cache(Redis)を利⽤ するため、dockerが必要になります
  3. Serverpodの主な機能 • コードの自動生成 • ORMとリレーション • DBマイグレーション • 認証 •

    ファイルアップロード • サーバーの可視化 • データストリーミング • キャッシュ • タスクスケジューリング • ヘルスチェック • 簡単なデプロイ • ビルトインのWEBサーバー • など
  4. Serverpodの主な機能 • コードの自動生成 • ORMとリレーション • DBマイグレーション • 認証 •

    ファイルアップロード • サーバーの可視化 • データストリーミング • キャッシュ • タスクスケジューリング • ヘルスチェック • 簡単なデプロイ • ビルトインのWEBサーバー • など こちら側の機能を紹介します
  5. Serverpodの主な機能 • コードの自動生成 • ORMとリレーション • DBマイグレーション • 認証 •

    ファイルアップロード • サーバーの可視化 • データストリーミング • キャッシュ • タスクスケジューリング • ヘルスチェック • 簡単なデプロイ • ビルトインのWEBサーバー
  6. 例) エンドポイントの実装からコードを自動生成する 1. サーバー側のエンドポイントを実装 2. $ serverpod generate を実行 server/lib/src/generated

    以下にサーバー側のコード、client/lib/src/protocol 以下にクライアント 側のコードが生成される。 class ExampleEndpoint extends Endpoint { Future<String> hello(Session session, String name) async { return 'Hello $name'; } } コードの自動生成
  7. 生成されたクライアントのメソッドをFlutterアプリから呼び出すことで、実 装したエンドポイントへのアクセスができる。 コードの自動生成 // 自動生成されたクライアントクラス final client = Client('https://myapi.com/'); //

    エンドポイントのアクセス final result = await client.example.hello('Serverpod'); // 'Hello Serverpod' print(result); class ExampleEndpoint extends Endpoint { Future<String> hello(Session session, String name) async { return 'Hello $name'; } } エンドポイントでは引数 sessionを利⽤することで、 以下へのアクセスが可能になる • HTTPリクエストの情報 • 認証情報 • データベース • キャッシュ • ストレージ
  8. コードの自動生成 エンドポイントの引数や戻り値にはStringやint等に加えて、独自のモデルや エラーを作成して利用することもできる。 class: Example fields: message: String createdAt: DateTime

    exception: InvalidArgumentException fields: message: String // Server code Future<Example> hello(Session session, String name) async { if (name.isEmpty) { throw InvalidArgumentException(message: 'Name cannot be empty'); } return Example(message: 'Hello $name', createdAt: DateTime.now()); } // Flutter code // InvalidArgumentExceptionが発生 final result = await client.example.hello(''); // Exampleオブジェクトが取得できる final result2 = await client.example.hello('Serverpod');
  9. コードの自動生成 classやenum、exceptionのモデルが作成できる。 以下の型やNull許容をサポートし、生成したモデルを使用することも可能。 • bool • int • double •

    String • Duration • DateTime • ByteData • UuidValue • List<E> • Map<K, V> # enumの定義例 enum: Animal serialized: byName values: - dog - cat - bird # classの定義例 class: User fields: name: String favoriteAnimal: List<Animal> createdAt: DateTime
  10. Serverpodの主な機能 • コードの自動生成 • ORMとリレーション • DBマイグレーション • 認証 •

    ファイルアップロード • サーバーの可視化 • データストリーミング • キャッシュ • タスクスケジューリング • ヘルスチェック • 簡単なデプロイ • ビルトインのWEBサーバー
  11. ORMとリレーション モデルにtableキーとテーブル名を追加することでORMが自動生成される。 class: User table: user # 追加 fields: ...

    // データの作成 User.db.insertRow(session, user); // データの取得 User.db.findById(session, userId); // データの更新 User.db.updateRow(session, newUser); // データの削除 User.db.deleteRow(session, user); // 自動生成されたUserモデル abstract class User extends _i1.TableRow { ... // DBアクセスするためのリポジトリ static const db = UserRepository._(); ... } $ serverpod generate 複数のデータもCRUD操作も可能
  12. ORMとリレーション relationキーワードを設定することでリレーションが設定できる。 データへのアクセスを簡略化するために、オブジェクトを指定してリレー ションを設定することが可能。 class: User table: user fields: #

    IDのリレーションを指定する場合 addressId: int, relation(parent=address) # オブジェクトのリレーションを指定する場合 address: Address?, relation class: Address table: address fields: street: String
  13. オブジェクトのリレーションを指定することで一度でリレーションしたデー タの取得が可能になる。 一度で取得するには includeオプションを指定する ORMとリレーション Future<User?> getUser(Session session, int userId)

    async { // Addressオブジェクトを取得し、 Userモデルにセットして返す // イメージ: {...略..., "addressId":1,"address":{"id":1,"street":"hoge city"}} return await User.db.findById(session, userId, include: User.include(address: Address.include())); }
  14. ORMとDBマイグレーション トランザクションやページネーションの実装も可能。 // トランザクション: Addressオブジェクトを取得し、 Userモデルにセットして返す return await session.dbNext.transaction<User>((transaction) async

    { await Address.db.insertRow(session, address, transaction: transaction); return await User.db.insertRow(session, user, transaction: transaction); }); // ページネーション: limit: 1回で取得できる最大レコード数 , offest: レコードを取得する開始点 final users = await User.db.find( session, limit: 10, orderBy: (t) => t.name, // 名前順 offset: 30, );
  15. Serverpodの主な機能 • コードの自動生成 • ORMとリレーション • DBマイグレーション • 認証 •

    ファイルアップロード • サーバーの可視化 • データストリーミング • キャッシュ • タスクスケジューリング • ヘルスチェック • 簡単なデプロイ • ビルトインのWEBサーバー
  16. Serverpodの主な機能 • コードの自動生成 • ORMとリレーション • DBマイグレーション • 認証 •

    ファイルアップロード • サーバーの可視化 • データストリーミング • キャッシュ • タスクスケジューリング • ヘルスチェック • 簡単なデプロイ • ビルトインのWEBサーバー
  17. 認証(サーバー側の実装) 1. serverpod_auth_server モジュールのインストール 2. マイグレーションの作成 3. Firebaseの秘密鍵ファイルを配置 server/config/firebase_service_account_key.json に配置

    4. マイグレーションを適用してサーバーを実行 $ serverpod create-migration 認証に使⽤するテーブル等を⽣成する $ dart pub add serverpod_auth_server Firebaseプロジェクトの作成・設定は 割愛いたします 🙇 ※ .gitignoreに記載がないので注意 $ dart run bin/main.dart --apply-migrations
  18. 認証(クライアント・アプリ側の実装) 1. 各モジュールのインストール • クライアント: serverpod_auth_client • アプリ ◦ Serverpod認証

    : serverpod_auth_shared_flutter / serverpod_auth_firebase_flutter ◦ Firebase認証: google_sign_in / firebase_core / firebase_auth 2. Firebaseの設定 flutterfire_cli等で設定を実施 アプリ側の設定の詳細は割愛いたします🙇
  19. 認証(クライアント・アプリ側の実装) 3. ClientとSessionManagerの作成 • SessionManager : ユーザーの認証情報を管理する役割 client = Client(

    'http://$localhost:8080/', authenticationKeyManager: FlutterAuthenticationKeyManager(), )..connectivityMonitor = FlutterConnectivityMonitor(); sessionManager = SessionManager(caller: client.modules.auth); await sessionManager.initialize();
  20. 認証(クライアント・アプリ側の実装) 4. Googleでのサインインの実装 // Google認証後にFirebaseに登録する final googleUser = await GoogleSignIn().signIn();

    final googleAuth = await googleUser!.authentication; final googleAuthCredential = GoogleAuthProvider.credential( accessToken: googleAuth.accessToken, idToken: googleAuth.idToken); final credential = await FirebaseAuth.instance.signInWithCredential(googleAuthCredential); // FirebaseのidTokenを取得する(googleAuthのidTokenではない!) final idToken = await credential.user!.getIdToken(); // Serverpodのauthモジュールを使ってサーバー認証 final response = await client.modules.auth.firebase.authenticate(idToken!); if (response.success) { // 認証成功の場合、セッションマネージャーにユーザー情報を登録する await sessionManager.registerSignedInUser(response.userInfo!, response.keyId!, response.key!); }
  21. 認証 認証した後はセッションマネージャーやセッションからユーザーID等が取得 できる。 // アプリ側 final user = sessionManager.signedInUser; //

    サーバー側 Future<String> hello(Session session, String name) async { final userId = await session.auth.authenticatedUserId; return 'Hello $name, user id is $userId'; }
  22. Serverpodの主な機能 • コードの自動生成 • ORMとリレーション • DBマイグレーション • 認証 •

    ファイルアップロード • サーバーの可視化 • データストリーミング • キャッシュ • タスクスケジューリング • ヘルスチェック • 簡単なデプロイ • ビルトインのWEBサーバー
  23. Serverpodの主な機能 • コードの自動生成 • ORMとリレーション • DBマイグレーション • 認証 •

    ファイルアップロード • サーバーの可視化 • データストリーミング • キャッシュ • タスクスケジューリング • ヘルスチェック • 簡単なデプロイ • ビルトインのWEBサーバー
  24. サーバーの可視化 Serverpod insight アプリケーションを使っ て、サーバーの状態が確認できる。 • リクエストの詳細 ◦ どのエンドポイントがコールされたか ◦

    リクエスト日時 ◦ 応答速度 など • サーバーのヘルスチェック ◦ CPU/メモリの使用率など サーバー側にログ出⼒を追加することで、 詳細なログの監視も可能になる