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

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

CyberAgent
March 21, 2024
430

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

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

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/メモリの使用率など サーバー側にログ出⼒を追加することで、 詳細なログの監視も可能になる