BedrudはFiberウェブフレームワークを使用しています(Go向けのExpressライクなAPI)。
ルーティングロジック
ルートはinternal/server/server.goで定義されています。ミドルウェアやプレフィックスの適用を容易にするため、ルートをグループ化しています。
メイングループ:
/api/auth: 認証用の公開ルートと保護ルート。/api/room: ルーム管理用の保護ルート。/api/admin:superadminロールのユーザーに限定されたルート。/livekit: 組み込みのLiveKit音声・ビデオサーバーにリクエストを転送する特別なプロキシグループ。
特殊なハンドラロジック
ルーム管理 (internal/handlers/room.go)
RoomHandlerはBedrudのルームメタデータとLiveKitのメディアエンジン間の変換を行います。
1. ルーム作成
POST /api/room/createでルームが作成される際:
- 正規化: ルーム名はトリムされ、小文字に変換されます。
- 自動生成: 名前が指定されていない場合、BedrudはランダムなURLセーフな名前を生成します(例:
fancy-blue-whale)。 - 同期作成: バックエンドはまず内部LiveKit APIを呼び出してメディアセッションを作成し、その後ローカルデータベースにメタデータを保存します。
2. 参加とトークン
POST /api/room/joinでユーザーが参加する際:
- アクセス制御: バックエンドはルームが存在するか、ユーザーが承認されているかを確認します。
- トークン生成: 署名付きJWT(Join Token)が以下の内容で生成されます:
Identity: BedrudのユーザーID。Name: ユーザーの表示名。Grants:CanJoin、CanPublish、CanSubscribeなどの特定の権限。
- クライアントハンドシェイク: フロントエンドはローカルのルームメタデータとLiveKitトークンの両方を受け取り、WebRTC接続を開始します。
管理者・ユーザー管理 (internal/handlers/users.go)
/api/admin配下のルートは、RequireAccess("superadmin")ミドルウェアによって厳格に保護されています。
1. ユーザー管理
UsersHandlerは管理者に以下の操作を許可します:
- 全ユーザーの取得: 認証プロバイダーや最終ログインメタデータを含む、登録済みユーザーの完全な一覧を取得します。
- ステータス更新: アカウントアクセスを即座に有効化または無効化します。ユーザーを無効化すると、ログインやトークンの更新が直ちにブロックされます。
2. ルーム概要
管理者ルートでは、作成者に関係なく、プラットフォーム全体のアクティブなルームと過去のルームの一覧を取得できます。これはプラットフォームモデレーションを目的としています。
リクエストライフサイクル
-
リクエスト受信: FiberがHTTPリクエストを受け取ります。
-
ミドルウェア:
recover: エラー発生時にサーバーのクラッシュを防ぎます。cors: Cross-Origin Resource Sharingを処理します。Protected: (オプション)Authorizationヘッダーの有効なJWTを確認します。
-
ハンドラ:
internal/handlers内の関数が呼び出されます。c.BodyParserを使用してJSONボディ(もしあれば)を解析します。- 必要なServiceまたはRepositoryを呼び出します。
c.JSONを使用してJSONレスポンスを返します。
例: ルーム作成ハンドラ
func (h *RoomHandler) CreateRoom(c *fiber.Ctx) error {
var input struct {
Name string `json:"name"`
}
// 1. Parse Input
if err := c.BodyParser(&input); err != nil {
return c.Status(400).JSON(fiber.Map{"error": "Invalid input"})
}
// 2. Business Logic (via Repository)
room := &models.Room{Name: input.Name}
if err := h.roomRepo.Create(room); err != nil {
return c.Status(500).JSON(fiber.Map{"error": "Failed to create room"})
}
// 3. Response
return c.Status(201).JSON(room)
}静的ファイル(フロントエンド)
ウェブフロントエンドはビルド時にGoバイナリに埋め込まれます。Fiberはfilesystem.Newを使用してfrontend/ディレクトリからReactファイルを配信します。
/apiで始まらないルートはすべて、Reactアプリのindex.htmlにリダイレクトされます。これにより、ページリフレッシュ時の404エラーなしでクライアントサイドルーティングが有効になります。