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で参照させるべきか?」みたいなところも出てきているので、手を動かして何かを作ることは大事ですね。