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
Serverpodを活用したDartのフルスタックアプリケーション開発
Search
CyberAgent
PRO
March 21, 2024
0
430
Serverpodを活用したDartのフルスタックアプリケーション開発
Dartでフルスタックにアプリケーション開発ができるServerpodの機能や実装方法について
CyberAgent
PRO
March 21, 2024
Tweet
Share
More Decks by CyberAgent
See All by CyberAgent
KDD2024参加報告
cyberagentdevelopers
PRO
1
310
FastlyとfalcoでNode.jsレスなWebサーバーの構築: IPTV版ABEMAアプリのインフラ刷新
cyberagentdevelopers
PRO
1
60
Amebaチョイス立ち上げの裏側 ~ 依存システムとの闘い ~
cyberagentdevelopers
PRO
1
81
マイグレーションコード自作して File-Based Routing に自動移行!! ~250 ページの歴史的経緯を添えて~
cyberagentdevelopers
PRO
2
34
コードメトリクス計測による課題可視化と品質確保
cyberagentdevelopers
PRO
1
55
サイバーエージェントにおけるインナーソーシングの取り組み
cyberagentdevelopers
PRO
3
1.5k
ABEMAにおけるLLMを用いたコンテンツベース推薦システム導入と効果検証
cyberagentdevelopers
PRO
6
3.1k
クリエイティブ制作領域の データ活用を0から推進した話
cyberagentdevelopers
PRO
3
910
opt-in camera:カメラによる行動計測におけるオプトインの仕組みの実現
cyberagentdevelopers
PRO
3
880
Featured
See All Featured
RailsConf 2023
tenderlove
28
840
How GitHub (no longer) Works
holman
311
140k
Designing Experiences People Love
moore
138
23k
Scaling GitHub
holman
458
140k
How GitHub Uses GitHub to Build GitHub
holman
473
290k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
43
6.5k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
159
15k
The Art of Programming - Codeland 2020
erikaheidi
51
13k
Art, The Web, and Tiny UX
lynnandtonic
296
20k
We Have a Design System, Now What?
morganepeng
49
7.1k
BBQ
matthewcrist
85
9.2k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
191
16k
Transcript
Serverpodを活用した Dartのフルスタックアプリケーション開発 2024/03/19 吉村 拓海
⾃⼰紹介 吉村 拓海 (Yoshimura Takumi) 株式会社サイバーエージェント 2023年5⽉ 中途⼊社 AI事業本部 アプリ運⽤カンパニー所属
モバイルアプリエンジニア
アプリ運用カンパニーとは • 小売企業様と協業して、アプリを中心としたデジタルでの購買体験の実 現を行う事業部
• Serverpodとは • Serverpodの使用方法 • Serverpodの主な機能 • まとめ アジェンダ
Serverpodとは
Serverpodとは • FlutterコミュニティのためにDartで書かれたアプリケーションサーバー • Dartでフルスタックにアプリケーションの開発ができる • サーバーサイドの実装をより簡潔に素早く実装できるようにすることを 目的に設計しており、多くのモジュールや仕組みが提供されている 今回は、実際にServerpodを利用してみた内容をお話しします。 (機能が多く網羅的ではないですが、ご了承ください🙇)
• Serverpodの使用方法
Serverpodの使用方法 Serverpodの使用方法 1. Serverpod cli のインストール 2. Serverpod プロジェクトの作成 $
dart pub global activate serverpod_cli $ serverpod create mypod mypod_server mypod_client mypod_flutter パッケージ が⽣成される
各パッケージの役割について Serverpodの使用方法 エンドポイントやWEBサーバーの実装、モデルやプロトコルの定義を持つ。 mypod_server mypod_client mypod_flutter サーバーと通信するためのクライアントの実装を持つ。 このパッケージはサーバー側の定義からコードが自動生成されるため実装不要。 Flutterアプリケーションの実装を持つ。clientパッケージに依存している。
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が必要になります
• Serverpodの主な機能
Serverpodの主な機能 • コードの自動生成 • ORMとリレーション • DBマイグレーション • 認証 •
ファイルアップロード • サーバーの可視化 • データストリーミング • キャッシュ • タスクスケジューリング • ヘルスチェック • 簡単なデプロイ • ビルトインのWEBサーバー • など
Serverpodの主な機能 • コードの自動生成 • ORMとリレーション • DBマイグレーション • 認証 •
ファイルアップロード • サーバーの可視化 • データストリーミング • キャッシュ • タスクスケジューリング • ヘルスチェック • 簡単なデプロイ • ビルトインのWEBサーバー • など こちら側の機能を紹介します
Serverpodの主な機能 • コードの自動生成 • ORMとリレーション • DBマイグレーション • 認証 •
ファイルアップロード • サーバーの可視化 • データストリーミング • キャッシュ • タスクスケジューリング • ヘルスチェック • 簡単なデプロイ • ビルトインのWEBサーバー
サーバー側で実装したモデルやエンドポイントから、サーバー側のルーティン グやクライアントのコードを自動生成できる。 • サーバー・アプリ間のプロトコルやモデルが共通で利用できる • サーバー側のエンドポイントのルーティングの実装が不要 • 生成されたクライアントを利用することで、メソッドコールするようにエンド ポイントへのアクセスができる コードの自動生成
例) エンドポイントの実装からコードを自動生成する 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'; } } コードの自動生成
生成されたクライアントのメソッドを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リクエストの情報 • 認証情報 • データベース • キャッシュ • ストレージ
コードの自動生成 エンドポイントの引数や戻り値には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');
コードの自動生成 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
Serverpodの主な機能 • コードの自動生成 • ORMとリレーション • DBマイグレーション • 認証 •
ファイルアップロード • サーバーの可視化 • データストリーミング • キャッシュ • タスクスケジューリング • ヘルスチェック • 簡単なデプロイ • ビルトインのWEBサーバー
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操作も可能
ORMとリレーション relationキーワードを設定することでリレーションが設定できる。 データへのアクセスを簡略化するために、オブジェクトを指定してリレー ションを設定することが可能。 class: User table: user fields: #
IDのリレーションを指定する場合 addressId: int, relation(parent=address) # オブジェクトのリレーションを指定する場合 address: Address?, relation class: Address table: address fields: street: String
オブジェクトのリレーションを指定することで一度でリレーションしたデー タの取得が可能になる。 一度で取得するには 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())); }
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, );
Serverpodの主な機能 • コードの自動生成 • ORMとリレーション • DBマイグレーション • 認証 •
ファイルアップロード • サーバーの可視化 • データストリーミング • キャッシュ • タスクスケジューリング • ヘルスチェック • 簡単なデプロイ • ビルトインのWEBサーバー
DBマイグレーション 作成したモデルからマイグレーションのファイルが生成できる。 $ serverpod create-migration を実行 以下のフラグを指定して実行することでマイグレーションを適用ができる。 migrationsフォルダが⽣成される $ dart
run bin/main.dart --apply-migrations 個別でマイグレーションの対象にしないように 設定することも可能 マイグレーションだけ適応することも可能
Serverpodの主な機能 • コードの自動生成 • ORMとリレーション • DBマイグレーション • 認証 •
ファイルアップロード • サーバーの可視化 • データストリーミング • キャッシュ • タスクスケジューリング • ヘルスチェック • 簡単なデプロイ • ビルトインのWEBサーバー
Serverpodでは以下の認証が簡単に実装できる。 • Eメール • Google • Apple • Firebase 認証
Firebase経由でのGoogle認証の実装例について説明します。
認証(サーバー側の実装) 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
認証(クライアント・アプリ側の実装) 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等で設定を実施 アプリ側の設定の詳細は割愛いたします🙇
認証(クライアント・アプリ側の実装) 3. ClientとSessionManagerの作成 • SessionManager : ユーザーの認証情報を管理する役割 client = Client(
'http://$localhost:8080/', authenticationKeyManager: FlutterAuthenticationKeyManager(), )..connectivityMonitor = FlutterConnectivityMonitor(); sessionManager = SessionManager(caller: client.modules.auth); await sessionManager.initialize();
認証(クライアント・アプリ側の実装) 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!); }
認証 認証した後はセッションマネージャーやセッションからユーザー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'; }
Serverpodの主な機能 • コードの自動生成 • ORMとリレーション • DBマイグレーション • 認証 •
ファイルアップロード • サーバーの可視化 • データストリーミング • キャッシュ • タスクスケジューリング • ヘルスチェック • 簡単なデプロイ • ビルトインのWEBサーバー
ファイルアップロード ファイルアップロードするためのモジュールがサポートされている。 デフォルトの機能としてデータベースにファイルバイナリの保存をすることができるが、クラウドスト レージを使用するように推奨されている。 • Google Cloud Storage ◦ serverpod_cloud_storage_gcp
• Amazon S3 ◦ serverpod_cloud_storage_s3
ローカル環境のストレージにファイルを保存する場合は、ファイル操作する ためのインターフェースを実装する必要がある。 やりたかったこと • ローカルにS3互換のMinIOコンテナを起動 • ServerpodからローカルのMinIOに接続し操作する ◦ 提供されているモジュールのホスト名が以下のように指定されており、ローカルホスト を設定できなさそうだった
'https://$bucket.s3-$region.amazonaws.com' ファイルアップロード
Serverpodの主な機能 • コードの自動生成 • ORMとリレーション • DBマイグレーション • 認証 •
ファイルアップロード • サーバーの可視化 • データストリーミング • キャッシュ • タスクスケジューリング • ヘルスチェック • 簡単なデプロイ • ビルトインのWEBサーバー
サーバーの可視化 Serverpod insight アプリケーションを使っ て、サーバーの状態が確認できる。 • リクエストの詳細 ◦ どのエンドポイントがコールされたか ◦
リクエスト日時 ◦ 応答速度 など • サーバーのヘルスチェック ◦ CPU/メモリの使用率など サーバー側にログ出⼒を追加することで、 詳細なログの監視も可能になる
まとめ
まとめ • Serverpodを使用することでサーバーサイドからクライアントアプリま でフルスタックにDartで開発ができる • 提供されたモジュールやコードの自動生成によってサーバー側のコード を少なく機能実装ができる • サーバー・アプリ間でのモデルが共通化されているため一貫性を保つこ とができる
ご清聴ありがとうございました