Googleスプレッドシートを簡易DBとして使う場合、ブラウザ画面から直接シートへ書き込むよりも、Google Apps ScriptをAPIサーバーのように使い、Webアプリ側のサーバー処理から中継する構成にすると扱いやすくなります。
この記事では、外部WebアプリからGAS APIへアクセスし、スプレッドシート上の顧客DBへ一覧取得、個別取得、登録、更新、論理削除を行う実装パターンをまとめます。
以前まとめたGoogleスプレッドシートを簡易DBとして使うMVP構成のアイデアは構想寄りの記事でした。今回は、その考え方を実装に落とした記事です。
全体構成
構成は次のようにします。
ブラウザ画面
↓
Webアプリ側API / Node.js / Next.js API Route
↓
GAS Web API
↓
GoogleスプレッドシートDB
重要なのは、ブラウザ側JavaScriptからGAS APIを直接呼び出さないことです。GAS側の認証に使うAPI_TOKENをブラウザへ置くと、利用者から見えてしまいます。
そのため、ブラウザからは自分のWebアプリ側APIへアクセスし、Webアプリ側APIがAPI_TOKENを付けてGASへ中継します。

使う場面
この構成は、次のような小規模な業務アプリや試作に向いています。
- 社内向けの簡易顧客管理
- 問い合わせ、予約、作業履歴の管理
- スマホ入力フォームと管理用スプレッドシートをつなぐ仕組み
- 本格DBへ移行する前のMVP
- 管理者がスプレッドシート上で直接データを確認したい業務
反対に、大量アクセス、複雑な検索、高度な権限管理、厳密なトランザクションが必要な場合は、SupabaseやPostgreSQLなどの本格DBを検討した方が安全です。
シート設計
サンプルでは、顧客DB と ログ の2シートを使います。
顧客DB の1行目には、次のヘッダーを置きます。
| 列名 | 役割 |
|---|---|
| id | レコードを識別するUUID |
| createdAt | 作成日時 |
| updatedAt | 更新日時 |
| deletedAt | 論理削除日時 |
| version | 更新回数の目安 |
| name | 名前 |
| email | メールアドレス |
| tel | 電話番号 |
| status | 状態 |
| memo | メモ |
IDに行番号を使うと、並び替えや削除で参照が崩れます。スプレッドシートをDB代わりに使う場合でも、id 列を用意してUUIDを入れておくと、後から本格DBへ移行しやすくなります。
ログ シートには、操作履歴を残します。
| 列名 | 役割 |
|---|---|
| loggedAt | ログ記録日時 |
| action | list / get / create / update / delete |
| targetSheet | 対象シート |
| targetId | 対象ID |
| status | success または error |
| message | エラー内容など |

GAS側APIの役割
GAS側では、action の値で処理を分けます。
| action | 処理 |
|---|---|
| list | 削除されていないレコードの一覧取得 |
| get | id を指定して1件取得 |
| create | 新規登録 |
| update | id を指定して更新 |
| delete | deletedAt を入れる論理削除 |
GAS側の主な実装ポイントは次の通りです。
- スクリプトプロパティにAPI_TOKENを保存する
Utilities.getUuid()でUUIDを発行する- 削除は行を消さず、
deletedAtを入れる論理削除にする - 書き込み処理はLockServiceで同時実行を抑える
- 列番号固定ではなく、ヘッダー名ベースで値を組み立てる
- エラー時もJSONで結果を返す
- 操作ログを
ログシートに残す

GAS側の実装例です。
コードを読み込み中...志布志市いくつ?のランキング機能で使う想定
この構成は、公開ツールの志布志市いくつ?にランキング機能を追加する場合のデータ保存先としても利用しやすいです。
たとえば、ゲームをクリアしたあとにプレイヤー名、盤面サイズ、クリアタイム、登録日時を送信し、GAS API経由でGoogleスプレッドシートへ保存します。画面側ではランキング一覧を取得し、盤面サイズごとに上位タイムを表示します。
志布志市いくつ?のゲーム画面
↓ クリアタイムと名前を送信
Webアプリ側API
↓ API_TOKENを付けて中継
GAS Web API
↓
GoogleスプレッドシートのランキングDB
この用途では、scoreId、boardSize、playerName、clearTimeMs、createdAt、deletedAt のような列を用意すると管理しやすくなります。公開ランキングとして使う場合でも、メールアドレスや個人情報を保存せず、表示名とスコアだけに絞ると運用しやすいです。
ランキングのように書き込み件数が増える可能性がある機能では、最初はGoogleスプレッドシートでMVPを作り、アクセス数や登録件数が増えたらSupabaseやPostgreSQLへ移す前提で設計しておくと安全です。
Webアプリ側で中継する
Webアプリ側では、ブラウザから受けたリクエストをGAS APIへ中継します。
この例ではNode.jsの小さなローカルサーバーを使っていますが、実運用ではNext.jsのAPI Route、Vercel Functions、その他のサーバー側処理に置き換えられます。
.env には次のように設定します。
コードを読み込み中...GAS_API_TOKEN はサーバー側だけで使います。ブラウザへ返すHTMLやJavaScriptには含めません。
Webアプリ側APIの中継サンプルです。
コードを読み込み中...APIリクエストの例
GAS APIへは、サーバー側から次のようなJSONを送ります。
{
"token": "YOUR_API_TOKEN",
"action": "create",
"data": {
"name": "サンプル顧客",
"email": "sample@example.com",
"tel": "000-0000-0000",
"status": "有効",
"memo": "初回登録"
}
}
成功時は次のようなレスポンスを返します。
{
"ok": true,
"action": "create",
"result": {
"id": "uuid"
}
}
失敗時も、画面側で扱いやすいようにJSONで返します。
{
"ok": false,
"action": "create",
"error": "エラーメッセージ"
}
再利用するときのチェックリスト
別案件でこの構成を使う場合は、次の順番で確認すると安全です。
- スプレッドシートにDB用シートとログシートを作る
- 1行目にヘッダーを入れる
- Apps Scriptへ
Code.gsを貼り付ける SPREADSHEET_IDとシート名を実際の値に変える- スクリプトプロパティに
API_TOKENを設定する - GASをWebアプリとしてデプロイする
- Webアプリ側サーバーの
.envにGAS URLとAPI_TOKENを設定する list、create、update、deleteを順に確認する- ログシートに成功、失敗の履歴が残るか確認する
- 個人情報や案件固有データを公開資料へ載せていないか確認する
注意点
GoogleスプレッドシートDBは便利ですが、本格DBではありません。
特に、次の条件が出てきたら早めに移行先を検討します。
- レコード数が数千件から数万件へ増える
- 検索条件が複雑になる
- 同時書き込みが多くなる
- ユーザー別の細かい権限管理が必要になる
- 個人情報や契約情報を厳密に管理する必要がある
- 履歴、承認、ロールバックなどの業務要件が増える
ただし、最初のMVPや社内向けの小さな業務改善では、スプレッドシートをDB代わりにする構成はかなり有効です。管理者がデータを直接確認でき、サーバーやDBを用意しなくても試せるため、現場業務の流れを素早く検証できます。
関連記事
- Googleスプレッドシートを簡易DBとして使うMVP構成のアイデア
- 志布志市いくつ?
- GASで作る工事現場向け写真付き報告書Webアプリ
- 古物商の現場入力をスマホ化したGAS Webアプリ開発対応事例
- GASでCacheServiceを使って重い処理を軽くする
- GASでHTML出力時に文字を安全にエスケープする
まとめ
Googleスプレッドシートを簡易DBとして使う場合でも、id、作成日時、更新日時、削除日時、ログを最初から持たせておくと、後から運用しやすくなります。
さらに、GAS APIをブラウザから直接呼ばず、Webアプリ側サーバーで中継することで、API_TOKENを公開せずに済みます。小規模な業務アプリを低コストで試しながら、将来はSupabaseやPostgreSQLへ移行できる形として使いやすい構成です。
