2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Convexの動作を理解する

Last updated at Posted at 2025-03-23

問題

@Sicut_studyさんの【図解解説】話題の神Reactフレームワークreact-serverで技術記事投稿サイトを開発するチュートリアル【@lazarv/react-server/Convex/TypeScript】
をやっていて、Convexがどう動いているのか分からなかったのでまとめます。

Convexとは

リアルタイムデータベースを中心にしたバックエンドサービスを提供するプラットフォームです。

やっていること

ConvexのProvider設定

src/app/ConvexClientProvider.tsx
src/app/ConvexClientProvider.tsx
"use client";
import { ConvexProvider, ConvexReactClient } from "convex/react";

const convex = new ConvexReactClient(import.meta.env.VITE_CONVEX_URL!);

export default function ConvexClientProvider({
  children,
}: {
  children: React.ReactNode;
}) {
  return <ConvexProvider client={convex}>{children}</ConvexProvider>;
}

アプリ内で、ConvexのConvexClientProviderを使えるようにする

src/app/(root).layout.tsx
import "./global.css";
import Header from "../components/Header";
import { Footer } from "../components/Footer";
import ConvexClientProvider from "./ConvexClientProvider";

export default function RootLayout({
  pageName,
  children,
}: React.PropsWithChildren<{
  pageName: React.ReactNode;
}>) {
  return (
    <html lang="ja">
      <body>
        <ConvexClientProvider> // ConvexClientProviderを設定
          <div className="flex flex-col min-h-screen">
            <Header pageName={pageName} />
            <main className="flex-grow">{children}</main>
            <Footer />
          </div>
        </ConvexClientProvider>
      </body>
    </html>
  );
}

ConvexのAPI作成

convex/artiles.ts
// Convex関数を作り、Convexと記事データをやり取りするファイル
// convexのコンソールから関数を確認できる

//  v オブジェクト
// 引数やデータのバリデーションを行うためのさまざまなユーティリティ関数を提供
// クエリやミューテーションの引数が特定の型や条件を満たしているかどうかを検証
import { v } from "convex/values";

// query Getリクエスト
// mutation POSTリクエスト
import { mutation, query } from "./_generated/server";

// 中略
export const getPopular = query({
    // get クエリはオプションの limit 引数を受け取る
    // limit 引数が提供された場合、その値を使用して取得する記事の数を制限
    // 提供されない場合は、すべての記事を取得
    args: {
        // limit 引数がオプションであり、数値型であることを指定
        limit: v.optional(v.number()),
    },
    handler: async (ctx, args) => {
        const { limit } = args;
        const articles = await ctx.db.query("articles").collect();

        const sortedArticles = articles
            .sort((a, b) => (b.viewCount ?? 0) - (a.viewCount ?? 0))
            // limit がある場合、その値を使用して配列の最初から limit の位置までの要素を抽出
            // limit がない場合(null または undefined の場合)、デフォルトで最初から10個の要素を抽出
            .slice(0, limit ?? 10);
    return sortedArticles.map((article) => {
            return {
                id: article._id,
                title: article.title,
                description: article.description,
                author: article.author,
                createdAt: article._creationTime,
                viewCount: article.viewCount,
            };
        });
    },
});
// 中略

Convexのコンソールから関数を確認できる

image.png

トップページからGET.popular.server.tsを呼び出す

src/app/page.tsx
const getArticles = async () => {
    // fetch は、JavaScriptの標準APIで、ネットワークリクエストを行うために使用される
    const response = await fetch(
        // 作成したAPIを叩く
        // src/app/api/articles/GET.popular.server.tsを呼ぶ
        "http://localhost:3000/api/articles/popular?limit=10",
    );
    // レスポンスをjson形式に変換
    const data = await response.json();
    return data;
};

export default async function Home() {
//中略

// PopularArticleList にarticlesを渡して描画
 <PopularArticleList articles={articles} />
//中略

サーバーサイドレンダリング (SSR)でGET.popular.server.tsを呼び出す

src/app/api/articles/GET.popular.server.ts
import { ConvexClient } from "convex/browser";
import { api } from "../../../../convex/_generated/api";

// VITE_CONVEX_URL サーバーやAPIのURLを指し、ConvexClientの接続先を指定
const convexUrl = import.meta.env.VITE_CONVEX_URL;
if (!convexUrl) {
        throw new Error("VITE_CONVEX_URL is not defined");
}

// ConvexClientクラスのインスタンスを作成
const client = new ConvexClient(convexUrl);

// request: Requestは、HTTPリクエストの情報を含むオブジェクト
export default async function GetBlogs(request: Request) {

// 中略

    //  JS標準のURL オブジェクトを作成
    // リクエストのURLを解析して、クエリパラメータなどにアクセスできる
    const url = new URL(request.url);

// 中略

    // new Response 新しい Response オブジェクトを作成
    const response = new Response(JSON.stringify(articles))
    // console.log("response", response);
    return response;

終わりに

Convexの動作を理解するのは難しかったですが、各コンポーネントのつながりがわかって勉強になりました。

参考

【図解解説】話題の神Reactフレームワークreact-serverで技術記事投稿サイトを開発するチュートリアル【@lazarv/react-server/Convex/TypeScript】

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?