concepts について
SpacetimeDB 開発者向けの概念ガイドです。テーブル、Reducer、リアルタイムサブスクリプション、イベントテーブル、モジュールを解説し、トランザクション規則や認証 ID、クライアントへのデータ配信を扱います。
主な機能
- 01テーブルとトランザクション型Reducerの解説
- 02サブスクリプションによるデータ同期
- 03イベントテーブルとモジュール構成の紹介
- 04実装・デバッグ手順
- 05認証 ID と認可のルール
活用シーン
- 01SpacetimeDB アプリのデータモデル設計
- 02クライアントの購読とデータ更新の計画
- 03認可ロジックと実装手順の確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ clockworklabs/ spacetimedb --skill conceptsインストール後、Claude Code で/conceptsを入力して読み込まれたか確認します。
詳細
SpacetimeDB の基本概念
SpacetimeDB は、サーバーでもあるリレーショナルデータベースです。アプリケーションロジックをモジュールとしてデータベースに直接アップロードできるため、従来の Web/ゲームサーバー層を完全になくせます。Rust、C#、C++ のモジュールは WebAssembly にコンパイルされ、TypeScript のモジュールは V8 上で実行されます。
重要なルール
- リデューサーはトランザクションです。 呼び出し元にデータを返しません。データの読み取りにはサブスクリプションを使用してください。
- リデューサーは決定的である必要があります。 リデューサーでは、ファイルシステム、ネットワーク、外部クロック、外部の乱数ソースを使用しないでください。SpacetimeDB が提供するタイムスタンプと決定的な乱数値には、リデューサーコンテキスト(
ctx)を使用してください。 - データはリデューサーの戻り値ではなく、テーブル/サブスクリプションを介して読み取ってください。 クライアントはサブスクライブしたクエリを通じてデータを取得します。
- 自動インクリメント ID は連番ではありません。 欠番は通常のことなので、順序付けには使用しないでください。タイムスタンプまたは明示的なシーケンス列を使用してください。
ctx.senderは認証済みプリンシパルです。 引数として渡された ID を決して信頼しないでください。
機能の実装チェックリスト
- バックエンド: データを保存するテーブルを定義する
- バックエンド: データを変更するリデューサーを定義する
- クライアント: テーブルをサブスクライブする
- クライアント: UI からリデューサーを呼び出す
- クライアント: テーブルのデータを表示する
デバッグチェックリスト
- SpacetimeDB サーバーは実行中ですか?(
spacetime start) - モジュールは公開されていますか?(
spacetime publish) - クライアントバインディングは生成されていますか?(
spacetime generate) - サーバーログでエラーを確認してください(
spacetime logs <db-name>) - リデューサーはクライアントから実際に呼び出されていますか?
テーブル
- プライベートテーブル(デフォルト):リデューサーとデータベース所有者のみがアクセスできます。
- パブリックテーブル:サブスクリプションを通じて、クライアントから読み取りアクセスできます。書き込みには引き続きリデューサーが必要です。
エンティティではなく、アクセスパターンに基づいてデータを整理してください。
Player PlayerState PlayerStats
id <-- player_id player_id
name position_x total_kills
position_y total_deaths
velocity_x play_time
リデューサー
リデューサーは、データベースの状態を変更するトランザクション関数です。アトミックに実行され、外部の世界とやり取りできず、呼び出し元にデータを返しません。構文については、言語ごとのサーバースキルを参照してください。
イベントテーブル
イベントテーブルは、リデューサー固有のデータをクライアントにブロードキャストします。行はクライアントキャッシュに保存されません(count() は 0 を返し、iter() は何も返しません)。onInsert コールバックのみが呼び出されます。
サブスクリプション
サブスクリプションは、データベースの行をクライアントにリアルタイムで複製します。
- サブスクライブする: 必要なデータを記述する SQL クエリを登録します
- 初期データを受け取る: 一致するすべての行がすぐに送信されます
- 更新を受け取る: サブスクライブした行が変更されると、リアルタイムで更新されます
- 変更に対応する: コールバック(
onInsert、onDelete、onUpdate)を使用します
ベストプラクティス:
- サブスクリプションは有効期間ごとにまとめる
- サブスクリプションを更新するときは、サブスクライブしてからサブスクライブを解除する
- クエリの重複を避ける
- 効率的なクエリにはインデックスを使用する
モジュール
モジュールには、データベース内で実行されるアプリケーションロジックが含まれます。
- テーブル: データスキーマを定義します
- リデューサー: 状態を変更する呼び出し可能な関数を定義します
- イベントテーブル: リデューサー固有のデータをクライアントにブロードキャストします
- ビュー: 計算されたデータの一部をクライアントに公開する読み取り専用関数です
- プロシージャ:(不安定)副作用を伴う関数です(HTTP リクエスト、
ctx.withTx)
サーバー側モジュールは、Rust、C#、TypeScript、C++ で記述できます。
ライフサイクル:記述 → コンパイル → 公開(spacetime publish)→ ホットスワップ(クライアントを切断せずに再公開)
ID
- Identity: ユーザーを識別する、長期間有効なグローバル一意識別子です。
- ConnectionId: 特定のクライアント接続を識別します。
- 認可には常に
ctx.sender/ctx.Sender/ctx.sender()を使用してください。
SpacetimeDB は、組み込みの SpacetimeAuth、Auth0、Clerk、Keycloak、Google、GitHub など、多くの OIDC プロバイダーに対応しています。