SupabaseとWP APIでランダムに記事を取得する仕組みを作ってみた

この記事はSupabase Advent Calendar 2024の19日目の内容で、ランダムに記事を取得する仕組みの作り方について紹介しています。SupabaseでViewを作成し、Supabase.jsを使用してデータを取得する方法が解説されています。WordPressのAPIも使用可能で、SupabaseのDBに記事情報があればWordPressのAPIを省略できます。Supabaseを選んだ理由やAI生成記事への適用についても触れられています。手を動かして実践することの重要性も強調されています。

広告ここから
広告ここまで

目次

    この記事「Supabase Advent Calendar 2024」19日目の記事です。ここでは、以前紹介したランダムにデータを取得する処理を活用して、ランダムに記事を取得する仕組みを作る方法を紹介します。

    やろうとしたこと

    最終的には過去記事を紹介するSNS投稿などもやりたいと思っています。その第一歩として、このサイト内でランダムに記事を紹介する仕組みを追加してみました。

    SupabaseでViewを作る

    すでに作成してあるものを使い、SupabaseでViewを新しく追加します。今回はベクトルデータは不要ですので、SELECTの対象から除外しました。ORDER BY random()を使ってランダムにデータを取れるようにしています。

    CREATE VIEW random_documents AS SELECT id,content,metadata FROM documents ORDER BY random();

    Supabase.jsでクエリを実行する

    Viewとインデックスどちらも用意できていれば、あとはSupabaseのSDKでデータを取得するだけです。fromの引数をView名にすることでデータが取得できますし、limitで件数も指定できます。

        const supabaseClient = createClient(
            context.cloudflare.env.SUPABASE_URL,
            context.cloudflare.env.SUPABASE_KEY
        )
        const { data, error } = await supabaseClient.from('random_documents').select("id,content,metadata").limit(10)
        if (error) {
            throw Error(error.message)
        }
        const postIds = data.map(item => Number(item.id.split(':')[0]))
        const response = await fetch(`https://your-wp.dev/wp-json/wp/v2/posts?include=${postIds.join(',')}`)

    RemixのLoaderに組み込んだ場合はこのようになります。Supabase.jsはフロントエンド側でも動かせる(はず)ですが、サーバー側で処理した方が将来的にキャッシュを入れたり追加の処理を挟んだりするのに良いかなと思ったのでloader側を選択しています。

    WordPressのAPIも呼び出していますが、SupabaseのDBに記事タイトルなど必要なものが入っているならば省略できます。もしそうでない場合は、/wp-json/wp/posts?include=1,2,55のように投稿IDをカンマ区切りで渡しましょう。

    export async function loader({ context}: LoaderFunctionArgs) {
        const supabaseClient = createClient(
            context.cloudflare.env.SUPABASE_URL,
            context.cloudflare.env.SUPABASE_KEY
        )
        const { data, error } = await supabaseClient.from('random_documents').select("id,content,metadata").limit(10)
        if (error) {
            throw new Response(error.message, {
                status: 500
            })
        }
        const postIds = data.map(item => Number(item.id.split(':')[0]))
        const response = await fetch(`https://your-wp.dev/wp-json/wp/v2/posts?include=${postIds.join(',')}`)
        return {
            randomPosts: await response.json()
        }
    }
    
    export default function RandomPosts() {
        const { randomPosts } = useLoaderData<typeof loader>()
        return (
            <div className='px-4 sm:px-0'>
                <ListPosts
                    header={{
                        title: "Random posts"
                    }}
                    posts={randomPosts}
                />
            </div>
        )
    }

    やってみて

    WordPress側でもやれないことはないと思います。今回Supabaseを選んだもう1つの理由は、「生成AI系の機能リリースと値付けに迷っているので、それまでの間Supabaseにリクエストを送る仕組みが欲しかった」というのもあります。とはいえいろいろと動かしてみると、「この記事って生成AIによるRAGで参照させるべきか?」みたいなところも出てきているので、手を動かして何かを作ることは大事ですね。

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark