はじめに
「バックエンドを作りたいけれど、認証・データベース・ストレージを一つひとつ構築するのは大変…」「Firebaseは便利だけど、NoSQLではなくSQLを使いたいし、ベンダーロックインも気になる…」
そんな悩みを抱えたことはありませんか?フロントエンド開発が高速化した今、バックエンドの構築スピードがプロジェクト全体のボトルネックになりがちです。
そこで注目したいのが「Nhost」です。Nhostは「The Open Source Firebase Alternative with GraphQL」を掲げるBaaS(Backend as a Service)で、PostgreSQL・GraphQL API・認証・ストレージ・サーバーレス関数といったバックエンドに必要な機能がワンセットになっています。この記事では、Nhostの基本から実践的な使い方まで、コピペで動くコード例とともに解説します。
Nhostとは
Nhostは、オープンソースのバックエンドプラットフォームです。データベースにPostgreSQL、GraphQL APIにHasuraを採用しており、「オープンソース」「GraphQL」「SQL」「優れた開発者体験」という4つのコンセプトを重視して開発されています。
GitHubで9,000以上のスターを獲得しているMITライセンスのプロジェクトで、マネージドのクラウドサービスとして使うことも、Docker Composeでセルフホスティングすることも可能です。
主な特徴
- PostgreSQLベース - Firebaseと違い、リレーショナルデータベースのPostgreSQLをそのまま使えます。SQLの知識や既存の資産を活かせるうえ、データのエクスポートも自由です
- GraphQL APIを自動生成 - Hasuraがテーブル定義から即座にGraphQL APIを生成します。CRUDのためのAPIを自分で書く必要はありません
- 認証機能を標準搭載 - メール/パスワード認証はもちろん、マジックリンク、OTP、GoogleやGitHubなどのソーシャルログインにも対応しています
- ストレージとサーバーレス関数 - ファイルのアップロード・配信を担うStorageと、Node.js(JavaScript/TypeScript)で書けるFunctionsが用意されています
- ロックインなし - すべてオープンソースの部品(PostgreSQL、Hasuraなど)で構成されているため、いつでもセルフホスティングに移行できます
インストール
Nhostを使い始める方法は主に2つあります。
1. クラウド版でプロジェクトを作成
最も手軽なのは Nhost Cloud にサインアップしてプロジェクトを作成する方法です。作成すると subdomain と region が発行され、すぐにバックエンドが使える状態になります。無料プランがあるので、個人開発や検証にも気軽に使えます。
2. CLIでローカル開発環境を構築
ローカルで完結した開発環境が欲しい場合は、Nhost CLIを使います。DockerさえあればPostgreSQL・Hasura・認証・ストレージ一式がローカルに立ち上がります。
# macOS / Linux
curl -L https://raw.githubusercontent.com/nhost/cli/main/get.sh | bash
# Homebrew
brew install nhost/tap/cli
# プロジェクトの初期化と起動
nhost init
nhost up
アプリケーション側には、JavaScript/TypeScript向けのSDKをインストールします。
# npm
npm install @nhost/nhost-js
# yarn
yarn add @nhost/nhost-js
# pnpm
pnpm add @nhost/nhost-js
なお、DartおよびFlutter向けのSDKも公式に提供されています。
基本的な使い方
クライアントの初期化
まずはNhostクライアントを作成します。subdomain と region には、Nhost Cloudのダッシュボードに表示されるプロジェクトの値を設定してください。
// lib/nhost.ts
import { createClient } from "@nhost/nhost-js";
export const nhost = createClient({
subdomain: "<your-subdomain>",
region: "<your-region>",
});
createClient() で作成したクライアントは、セッション管理を自動で行ってくれます。アクセストークンの更新やリクエストへの認可情報の付与を意識する必要はありません。
ユーザー登録とサインイン
認証機能は nhost.auth からアクセスします。メール/パスワードでのユーザー登録はこれだけです。
// ユーザー登録
const signUpResponse = await nhost.auth.signUpEmailPassword({
email: "user@example.com",
password: "secure-password-123",
});
// サインイン
const signInResponse = await nhost.auth.signInEmailPassword({
email: "user@example.com",
password: "secure-password-123",
});
console.log(signInResponse.body.session?.user?.email);
サインインに成功するとセッションが確立され、以降のGraphQLリクエストやストレージ操作には自動的に認証情報が付与されます。
GraphQLでデータを取得
Hasuraが自動生成したGraphQL APIは nhost.graphql.request() で呼び出せます。たとえば todos テーブルを作成していれば、次のように取得できます。
const response = await nhost.graphql.request({
query: `
query GetTodos {
todos(order_by: { created_at: desc }) {
id
title
done
}
}
`,
});
console.log(response.body.data?.todos);
データの追加もミューテーションを送るだけです。
const response = await nhost.graphql.request({
query: `
mutation InsertTodo($title: String!) {
insert_todos_one(object: { title: $title }) {
id
title
}
}
`,
variables: { title: "Nhostを試す" },
});
SQLでテーブルを定義すれば、対応するクエリとミューテーションが即座に使えるようになります。この「APIを書かない」体験がNhostの大きな魅力です。
ファイルのアップロード
画像などのファイルは nhost.storage で扱います。
const result = await nhost.storage.uploadFiles({
"file[]": [new File(["Hello Nhost!"], "hello.txt", { type: "text/plain" })],
});
console.log(result.body.processedFiles?.[0]?.id);
アップロードしたファイルにはIDが振られ、権限設定に応じてURL経由で配信できます。
サーバーレス関数の呼び出し
functions ディレクトリにTypeScriptファイルを置くだけで、サーバーレス関数としてデプロイされます。
// functions/helloworld.ts
import { Request, Response } from "express";
export default (req: Request, res: Response) => {
res.status(200).json({ message: `Hello, ${req.body.name ?? "World"}!` });
};
クライアントからは nhost.functions で呼び出します。
const result = await nhost.functions.post("/helloworld", {
name: "Nhost",
});
実践的なユースケース
ここでは、ReactでTodoアプリを作る例を見てみましょう。認証済みユーザーが自分のTodoだけを閲覧・追加できる、実際のアプリでよくある構成です。
Hasuraのパーミッション機能で「user_id が自分と一致する行だけ操作可能」というルールを設定しておけば、クライアント側のコードはシンプルに保てます。
// src/components/TodoList.tsx
import { useEffect, useState } from "react";
import { nhost } from "../lib/nhost";
interface Todo {
id: string;
title: string;
done: boolean;
}
export function TodoList() {
const [todos, setTodos] = useState<Todo[]>([]);
const [title, setTitle] = useState("");
const fetchTodos = async () => {
const response = await nhost.graphql.request({
query: `
query GetTodos {
todos(order_by: { created_at: desc }) {
id
title
done
}
}
`,
});
setTodos(response.body.data?.todos ?? []);
};
useEffect(() => {
fetchTodos();
}, []);
const addTodo = async () => {
if (!title.trim()) return;
await nhost.graphql.request({
query: `
mutation InsertTodo($title: String!) {
insert_todos_one(object: { title: $title }) {
id
}
}
`,
variables: { title },
});
setTitle("");
await fetchTodos();
};
return (
<div>
<input
value={title}
onChange={(e) => setTitle(e.target.value)}
placeholder="やることを入力"
/>
<button onClick={addTodo}>追加</button>
<ul>
{todos.map((todo) => (
<li key={todo.id}>
{todo.done ? "✅" : "⬜"} {todo.title}
</li>
))}
</ul>
</div>
);
}
ポイントは、認証・認可のロジックがクライアントコードにほとんど現れないことです。サインイン済みであればSDKが自動でトークンを付与し、行レベルの認可はHasura側のパーミッションが担保します。つまり、セキュリティルールをバックエンド側に集約しつつ、フロントエンドはデータの表示に集中できるのです。
このほかにも、Nhostは次のような場面で力を発揮します。
- MVPやプロトタイプの高速開発 - テーブルを定義するだけでAPIが手に入るため、アイデア検証までの時間を大幅に短縮できます
- モバイルアプリのバックエンド - Flutter SDKが提供されており、Webとモバイルでバックエンドをそのまま共有できます
- AI機能の組み込み - Nhost AIを使うと、PostgreSQLのデータに対するベクトル検索やLLM連携をマネージドで利用できます
まとめ
今回は、オープンソースのFirebase代替バックエンド「Nhost」を紹介しました。
- NhostはPostgreSQL・Hasura・認証・ストレージ・サーバーレス関数がワンセットになったBaaSです
- テーブルを定義するだけでGraphQL APIが自動生成され、CRUD用のAPIを書く必要がありません
@nhost/nhost-jsSDKを使えば、認証からデータ操作、ファイルアップロードまで数行のコードで実装できます- すべてオープンソースの部品で構成されているため、クラウド版からセルフホスティングへの移行も可能です
「SQLの柔軟性は手放したくない、でもバックエンド構築に時間はかけたくない」という方には、まさにうってつけの選択肢です。まずは無料のクラウド版でプロジェクトを作成し、GraphQLの自動生成を体験してみてください。きっとバックエンド開発の景色が変わるはずです。