【モダンなバックエンド開発!】 Convexって何?をFirebaseと比べて解説してみる
Convexとは
一言で説明すると、、、
「バックエンドの面倒なところ全部やってくれるスーパーライブラリ」
です!
アプリケーションを作成するためには、UI・UXやバックエンドのロジックだけではなく、やインフラ、データベースや認証など様々なことを考える必要があります。
- データベース設計・マイグレーション管理
- SQLによるデータベースからの取得・永続化
- ログインなどの認証機能
- AWSなどを使用したデータベース・APIサーバー構築や管理
- フロントとバックエンドを型安全に繋げる実装
- WebSocketの実装によるリアルタイム実装
などなど、、、
こうしたシステムを全てを自前で用意するのは大変であるため、外部ライブラリなどのサードパティ製品を使用します。例えばSQLにはPrisma、フレームワークですがLaravelの標準機能であるEloquentなどがあり、生のSQLを書かなくても直感的に実装ができます。OrvalやAdspidaを使用してバックエンドとフロントを型安全に扱い…など、こうした製品は事前に環境を構築する必要があり、さらに学習の必要もあります。
しかしこれらの悩みは、Convexが解決してくれます!
全てTypeScriptで実装可能
フロントとバックエンドで言語を分けることなく実装できます。そのため、openapi.jsonでの型定義を記述・気にすることなく型安全に実装することができます。
そもそものSQLの記述が不要
Prismaなどのクエリビルダーを使用して実装するといった必要がありません。query(取得)とmutation(挿入)といった2つの概念でSQLを記述しないシンプルな実装が可能です。この辺りをConvexが勝手にやってくれるということです。SupabaseはSQLを記述する必要があるため、この点で違いがあります。
// convex/tasks.ts
import { query, mutation } from "./_generated/server";
import { v } from "convex/values";
// 取得(SQLを書かずにこれだけ!)
export const get = query({
handler: async (ctx) => {
return await ctx.db.query("tasks").collect();
},
});
// 追加
export const add = mutation({
args: { text: v.string() },
handler: async (ctx, args) => {
await ctx.db.insert("tasks", {
text: args.text,
isCompleted: false,
});
},
});
マイグレーションの記述・管理が不要
テーブル定義はTypeScriptの記述により実装します。マイグレーションの管理などは不要です。
// convex/schema.ts - スキーマ定義(マイグレーション不要)
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";
export default defineSchema({
tasks: defineTable({
text: v.string(),
isCompleted: v.boolean(),
}),
});
トランザクションの記述が不要
複数のDB操作として分けて記述するだけでConvexが自動的にトランザクション処理をします。そのため、try catch といった特別な記述が不要です。
リアルタイム通信
Convexはデータベースの内容が即座にフロントエンドに反映される仕組みを持っています。モダンアプリケーションでは必須であり、リアルタイムチャットやホワイトボードといったコラボレーションの実装に必要です。これは自前でWebSocketを実装することなく、Convexで簡単に実装できます。
import { useQuery, useMutation } from "convex/react";
import { api } from "../convex/_generated/api";
function TaskList() {
// リアルタイムで取得(DBが更新されたら自動で再取得)
const tasks = useQuery(api.tasks.get);
// 追加関数
const addTask = useMutation(api.tasks.add);
return (
<div>
{tasks?.map(task => (
<div key={task._id}>{task.text}</div>
))}
<button onClick={() => addTask({ text: "新しいタスク" })}>
追加
</button>
</div>
);
}
バックエンドのインフラを考える必要がない
従来はAWSなどのクラウド使用してサーバーを構築してデプロイ、またログの監視やスケーリング、セキュリティなどの設計や実装をする必要がありました。しかしConvex自体がバックエンドのインフラを管理しているため、インフラを考える必要がありません。フロントをVercelでデプロイしConvexの簡単な設定をするだけで、アプリケーションを構築することができます。
認証機能
Convexでログイン機能を簡単に実装することができます。
結局Firebaseと何が違うの?
➡︎ バックエンドに必要なものがセットされている点は似ているが、根本的な思想に違いがある
Firebase の思想: 「柔軟性と選択肢」
「開発者よ、好きな方法を選べ」
- シンプルな処理? → クライアントから直接DBアクセスでいいよ
- 複雑な処理? → Cloud Functions書いてね
- 認証? → Firebase Authでも、カスタムでもいいよ
- ストレージ? → Firebase Storageでも、GCSでも、S3でもいいよ
= 自由度が高い代わりに、統一感がない
Convex の思想: 「統一性と一貫性」
「すべてをTypeScriptで、すべてを関数で」
- すべての処理 → 必ずバックエンド関数経由
- すべてのロジック → TypeScriptで書く
- すべてのデータアクセス → 型安全に
- クライアントはAPIを叩くだけ
= 制約が多い代わりに、混乱がない
Convexが向いているケース ✅
- MVP開発やスタートアップ: 素早くプロトタイプを作りたい
- リアルタイム機能が必要: チャット、コラボレーションツール
- 小〜中規模のアプリケーション: 個人プロジェクトやSaaS
- TypeScript/Reactエコシステム: 既にこれらを使っている
向いていないケース ❌
- 超大規模システム: 独自のインフラ最適化が必要
- 既存の複雑なデータベース: 既存DBとの統合が困難
- 特殊なデータベース要件: 複雑なSQLクエリが必須
- 長期的なコスト最適化が重要: 自前インフラの方が安い場合も
Convexの料金体系
- 無料枠: 月100万クエリまで無料
- 有料プラン: Starter ($25/月)、Professional ($65/月)など
まとめ
バックエンドの設計・環境構築~運用を考えることなく、
「サービスに必要な機能」に注力して実装することができる
というバックエンドの開発体験が大きく変わるライブラリというわけです!
参考にした・もっと見たい記事:
Discussion