見出し画像

Vercel Storage 試してみた。

こんにちは!フクロウラボ フロントエンドチームの岩元です。

今回のフクロウラボエンジニアブログでは
最近リリースされたVercelの新機能 Vercel Storage について調査しました!

※ こちらの記事は2023年5月の情報をもとに作成しております。

Vercel とは

React のフレームワークである Next.js などを開発している
Vercel 社が提供しているホスティングサービスです。
類似サービスとしては Netlify, GitHub Pages, Firebase Hosting などがあげられます。

Next.js の開発元であることもあり、Next.js のホスティングサポート
に特化したホスティングサービスですが、Nuxt.js, Astoro, Gastby などの
主要なフロントエンドフレームワークもサポートされています。

Vercel Storage とは

2023年5月1日 Vercel から発表された新機能で、
Vercel 上で管理できるサーバレスなデータベース機能です。

今回は 2023年5月1日に発表された Vercel Storage の下記3つについて、
Next.js v13.4.2 でそれぞれを使用したデモを交えながら
ご紹介していきたいと思います。

  • Vercel KV

  • Vercel Postgres

  • Vercel Blob 


Vercel KV とは

Vercel Storage で使用できる Redisデータベース です。

単純な Key-Valueデータ  JSONデータ を保持することができ、
後述する Vercel Postgres に比べると少しだけ速いです。
2023年5月17月現在はまだBate機能ですが使用することはできます。

リクエスト数やデータ容量に制限はありますが、
Hobbyプランでも1つ無料でデータベースを作成する事ができます。
料金や無料枠の制限の詳細は下記のページをご参考ください。

今回は Redis で扱うことのできるデータ形式の中から、
List を使用して簡易的なコメント一覧を作成してみました。

Redis の List 型は、順序付けされた文字列コレクションなので
IDや投稿者名などは記録されず、単純にコメントの一覧として使用します。

Vercel KVからのデータ取得は Next13 の API Routes を使用する場合
下記のように実装する事ができます。

// /src/app/api/vercel-kv/getComments/route.ts
import { NextResponse } from "next/server";
import { kv } from "@vercel/kv";

export async function GET(request: Request) {
  try {
    const comments = await kv.lrange("comments", 0, -1);
    return NextResponse.json(comments);
  } catch (e) {
    return NextResponse.json({ error: e });
  }
}

とても簡単に実装できますね!
画面側から呼び出す際は下記のように実装すればList内の
データの一覧を取得する事ができます。

// /src/app/vercel-kv/page.tsx
"use client";
import { useEffect, useState } from 'react';

async function getComments(): Promise<string[] | undefined> {
  const data = await fetch('/api/vercel-kv/getComments')
    .then((res) => res.json())
    .catch((err) => {
      throw err;
    });

  return data;
}

export default function NextKV() {
  const [comments, setComments] = useState<string[] | undefined>(undefined);

  useEffect(() => {
    const fetchData = async () => {
      const comments = await getComments();
      setComments(comments);
    };

    fetchData();
  }, []);

  return (
    <main>
      <h1>Comments</h1>
      <div>
        {comments?.map((comment, i) => (
          <p key={i}>{comment}</p>
        ))}
      </div>
    </main>
  );
}

データの追加方法、画面からの呼び出しの詳細などは
下記デモのリポジトリをご確認ください。

Redis では JSON 形式にも対応しているので、
上記のようなコメント一覧であれば ID をつけたり、投稿者名などを追加することもできそうですね!

データ取得・追加がとても単純で、今回データの追加で使用している
RPUSHでは存在しない List にデータを追加しようとすると
自動的に空の List を生成し、PUSHを行ってくれます。

現段階の無料プランだと1日に3000リクエストまでという制限があるので、
個人で使用するくらいにしか使えないかもしれないですね。

フクロウラボのバックエンドエンジニア 満江さん
Redis について聞いてみたところ「一般的にRedisは揮発性の高いインメモリ型のDBとして扱う事が多く、ログイン時のセッションデータ保持などに使われる事が多いです。今回岩元さんが作成されているデモのような使い方はほぼほぼしないですね笑」とのことでした 🫣 笑

Vercel KV ではデータの永続化が行われているので、今回のような実装もできますが、1日のリクエスト数などの制限を考えると、確かに満江さんが出してくださった例のログイン時のセッションデータ保持や、Vercel のユースケースとして紹介されているECサイトのショッピングカート機能として使用するのが良さそうです!


Vercel Postgres とは

Vercel Storageで使用できる サーバレスPostgresデータベースです。

データベーステーブル同士の複雑なトランザクションや、
各レコードデータの多様なデータ形式に対応することが可能です。

今回は users というテーブルを作成して、
ユーザーの一覧表示・検索・追加ができるデモを作成しました。

下記はVercel Postgresからデータを取得するAPIの実装例です。

// /src/api/vercel-postgres/getUsers/route.ts
import { sql } from "@vercel/postgres";
import { NextResponse } from "next/server";

export async function GET(request: Request) {
  try {
    const { rows } = await sql`select * from users;`
    return NextResponse.json({ rows });
  } catch (e) {
    return NextResponse.json({ error: e });
  }
}

下記はAPIの呼び出し側の実装例です。

// /src/vercel-postgres/page.tsx
"use client";
import { useEffect, useState } from 'react'

type User = {
  id: number
  name: string
  mail: string
}

async function getUsers(searchInput?: string): Promise<User[] | undefined> {
  const data = await fetch(`/api/vercel-postgres/getUsers${searchInput ? `?searchInput=${searchInput}` : ''}`)
    .then((res) => res.json())
    .catch((err) => {
      throw err
    })

  return data.rows
}

export default function NextPostgres() {
  const [users, setUsers] = useState<User[] | undefined>(undefined)

  useEffect(() => {
    const fetchData = async () => {
      const users = await getUsers();
      setUsers(users);
    }

    fetchData();
  }, []);

  return (
    <main>
      <table>
        <thead>
          <tr>
            <th>id</th>
            <th>name</th>
            <th>mail</th>
          </tr>
        </thead>
        <tbody>
          {users?.map((user) => (
            <tr key={user.id}>
              <td>{user.id}</td>
              <td>{user.name}</td>
              <td>{user.mail}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </main>
  )
}

こちらもデータの検索や追加の処理に関しては下記をご確認ください。

今まで Vercel にホスティングしつつ Supabase を使用していたような場合は
Vercel のみで完結できるようになるかもしれませんね!

今回のデモではORMなどは使用しませんでしたが、
Vercel公式のテンプレートでも用意されているように Prisma などを
使用して実装するのが良さそうです。

こちらも無料のHobbyプラン枠だと、1ヶ月あたりの計算時間が60時間までの為、本格的に使用するのであればProプランへのアップデートは必須になりそうです。


Vercel Blob とは

Vercel Storageで使用できるファイルストレージサービスで、
画像、動画、音声などのデータを保存・公開する事ができます。

公式の説明にもあるとおり、Amazon S3 の
代替として使用する事ができそうです。

現状、料金周りに関する情報はまだ公開されていませんでした。

2023年5月17月現在ではPrivate Bateとなっており、デモの作成はできませんでしたが、使用可能になり次第デモのリポジトリで試してみる予定です!


まとめ

Next13 の App router のリリースや、今回ご紹介した Vercel Storage
リリースなど、最近Vercelの勢いがすごいですね。

以前までは Next.js というフレームワークを出していて、
ホスティングも対応してくれているというくらいのイメージだったのですが
今回の Vercel StorageEdge Function などのリリースを見ると
AWS でいう RDS, S3, Lambda などの機能も賄えるようになってきており、
Vercel 単体で解決できる事がかなり増えてきています。

あとは Authenticator の機能ができれば、
殆どフロントの実装のみで解決できそうなので待ち遠しいところです!

この記事が気に入ったらサポートをしてみませんか?