Serverpod(+Flutter)挑戦メモ
まずは環境構築から
ServerpodをDartコマンドでインストール
dart pub global activate serverpod_cli
以下のコマンド使用できるようになったかを確認。
serverpod
DockerをHomebrewでインストール
brew install --cask docker
Docker Desktopもインストールされる。
インストール完了後、初回起動を済ませてHelperのインストールやチュートリアルを終わらせておく。
Serverpodの新規プロジェクトを作成
Docker Desktopが起動している状態で、 create
コマンドを使用することで新規プロジェクトが作成できる。
プロジェクトを作成したいディレクトリに移動して以下のコマンドを実行。
serverpod create {project_name}
Serverpodのドキュメントでは mypod
という名前プロジェクト作成を説明しています。
プロジェクト作成完了すると以下のような出力があった
プロジェクト名は、Serverpodのドキュメントと同じ mypod
にした場合の例です。
SERVERPOD CREATED 🥳
All setup. You are ready to rock!
Start your Serverpod by running:
$ cd mypod/mypod_server
$ docker compose up --build --detach
$ dart bin/main.dart
作成されたプロジェクトディレクトリには以下の3つのディレクトリが作成されている。
-
{project_name}_server
: サーバーサイドのコード -
{project_name}_client
: サーバーと通信するためのコード(自動生成のため直接編集はしない) -
{project_name}_flutter
: Flutterアプリ
サーバーを起動させる
cd {project_name}/mypod_server
docker-compose up -d --build
serverpod run
成功ログ
Starting mypod_server_postgres_1 ... done
Starting mypod_server_redis_1 ... done
Starting Serverpod.
• Automatic generate and reload are enabled.
Spinning up serverpod generate (this can take a few seconds).
Waiting for Postgres on localhost:8090.
Waiting for Redis on localhost:8091.
Setup complete. Starting the server.
SERVERPOD version: 0.9.8 mode: development
Insights listening on port 8081
Server id 0 listening on port 8080
コンテナの停止
docker-compose stop
PostgreSQLとは
オープンソースのリレーショナルデータベース管理システム(RDBMS)
参考
Redisとは
リモートディクショナリサーバーの略。
オープンソースのインメモリデータストア。
NoSQLでKey-Value Storeとして動作する。
Serverpod Insights
Serverpodのコンパニオンアプリ。
これを使えば、サーバーのログやヘルスメトリクスにアクセスすることができる。
Serverpodと同じバージョンのものをインストールして使用する。
Model / Entityの定義(Serialization)
yaml
で定義することもできるし、 freezed
当を使用して dart
で定義することもできる。
yamlファイルで定義してprotocolに置く独自の方法
### Information about a company.
class: Company
### DBの行を表す場合にTable Keyを定義する。lower_snake_caseを使用する。
table: company
fields:
### The name of the company.
name: String
### The date the company was founded, if known.
foundedDate: DateTime?
### A list of people currently employed at the company.
employees: List<Employee>
freezed
等を使用して定義する、慣れ親しんだ方法
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:serverpod_serialization/serverpod_serialization.dart';
part 'freezed_custom_class.freezed.dart';
part 'freezed_custom_class.g.dart';
class FreezedCustomClass with _$FreezedCustomClass {
const factory FreezedCustomClass({
required String firstName,
required String lastName,
required int age,
}) = _FreezedCustomClass;
factory FreezedCustomClass.fromJson(
Map<String, Object?> json,
SerializationManager serializationManager,
) =>
_$FreezedCustomClassFromJson(json);
}
config/generator.yaml
ファイルで、宣言する必要がある。
extraClasses:
- package:my_shared_package/my_shared_package.dart:FreezedCustomClass
fromJsonへのSerializationManagerパラメータ追加でエラーになる問題について
例外の定義とエラーハンドリング
シリアライズ可能なEntityを定義するのと同じようにyamlファイルで適宜可能。
exception: MyException
fields:
message: String
errorType: MyEnum
サーバー側では例外をスローする。
throw MyException(
message: 'Failed to do thingy',
errorType: MyEnum.thingyError,
);
アプリ側で例外をキャッチする。
try {
client.example.doThingy();
}
on MyException catch(e) {
print(e.message);
}
Database
モデルや例外と同様、protocol
ディレクトリにyamlファイルを作成する。
class: Company
table: company
fields:
name: String
foundedDate: DateTime?
serverpod generate
で generated/tables.pgsql
が生成される。
特定のフィールドをデータベースに保存したいが、クライアント側に提供したくない機密情報などは database
スコープを追加する。
class: UserData
fields:
name: String
password: String?, database
逆に(?)アクセスできるだけでサーバーに保存しないようにするには、 api
スコープを追加する。
インデックス
fieldsキーには、カラム名をカンマで区切ったリストを格納します。さらに、タイプキー(デフォルトはbtree)、ユニークキー(デフォルトはfalse)を追加することが可能です。
class: Company
table: company
fields:
name: String
foundedDate: DateTime?
employees: List<Employee>?, api
indexes:
company_name_idx:
fields: name
Parent/child リレーションシップ
class: Employee
table: employee
fields:
companyId: int, parent=company
name: String
birthday: DateTime
Session
エンドポイントのメソッドコール時の、コンテキスト情報。
セッションを使用して、サーバー内のDB、キャッシュ、認証、データストレージやメッセージングへアクセスできます。
また、HTTPリクエストオブジェクトの情報やIPアドレスにもアクセス可能。
以下のサブクラスにキャストすると、それぞれ追加情報が入手できる。
-
session as MethodCallSession
: エンドポイントやメソッドの名前、HttpRequestオブジェクトなどの追加プロパティを提供する。 session as StreamingSession
稀なユースケースとして、 Serverpod.instance?.createSession()
を使って手動でセッションを作ることも可能だが、 session.close()
メソッドでセッションを手動で閉じる必要がある。
Authentication
session.auth.authenticatedUserId
でユーザーID ( Future<int?>
) が取得できる。
Starting the server
の一連のコマンドをVS Codeでタスク化👍
{
"version": "2.0.0",
"tasks": [
{
"type": "shell",
"command": "docker-compose",
"args": [
"up",
"--build",
"--detach"
],
"group": "none",
"problemMatcher": [],
"options": {
"cwd": "mypod_server" // <- `xxx_server` ディレクトリのパスを指定する
},
"label": "docker-compose up"
},
{
"type": "shell",
"command": "dart",
"args": [
"bin/main.dart"
],
"group": "build",
"problemMatcher": [],
"options": {
"cwd": "mypod_server" // <- `xxx_server` ディレクトリのパスを指定する
},
"dependsOrder": "sequence",
"dependsOn": [
"docker-compose up",
],
"label": "run main.dart"
}
]
}