ユースケース開発React アプリケーションのためのOSDKチュートリアル:高度なToDoアプリケーションアーキテクチャと設定

注: 以下の翻訳の正確性は検証されていません。AIPを利用して英語版の原文から機械的に翻訳されたものです。

アーキテクチャと設定

以下の高度な ToDo アプリケーションの概要では、オントロジー SDK(オントロジー SDK)でアプリケーションを構築するために必要なアーキテクチャ、コンポーネント、機能、および前提条件を説明します。

はじめに

高度な ToDo アプリケーションの例にアクセスしてインストールするには、Code Workspaces アプリケーションを開き、+ 新規ワークスペースを作成するオプションを選択します。次に、VSコード > アプリケーションを選択し、厳選された例の一覧でアプリケーションを探します。

プラットフォームの Examples (Build with AIP) でアプリケーションを検索するか、Developer Console でオントロジー SDK のリファレンス例を検索することもできます。

VS Code ワークスペースでアプリケーションを作成し、高度な ToDo アプリケーションの例を選択します。

アプリケーションのアーキテクチャ

以下のセクションでは、作成できる高度な ToDo アプリケーションのアーキテクチャについて、ルーティング、クライアントの設定、コンポーネントでの使用を含めて説明します。

このアプリケーションは、以下の機能を備えたモダンな React アーキテクチャを採用しています。

  • データサービスフック: オントロジー SDK とのインタラクション(useProjects、useTasks など)をカプセル化します。
  • UI コンポーネント: 表示とユーザーインタラクションに特化したコンポーネントを含みます。
  • データ管理のための SWR (stale-while-revalidate) 戦略: キャッシュ、再検証、バックグラウンド更新を処理します。
  • コンポーネント固有のロジック: 各コンポーネントは、必要なデータにのみアクセスできます。

React のルーティング

高度な ToDo アプリケーションは、クライアントサイドのルーティングに React Router ↗ を使用します。ルーティングの設定は、アプリケーションのメインエントリーポイントで行います。

ルーティングの設定

このアプリケーションは、React Router の createBrowserRouter を次のシンプルな設定で使用します。

Copied!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 const router = createBrowserRouter( [ { path: "/", element: <Home />, }, { path: "/auth/callback", element: <AuthCallback />, }, ], { basename: import.meta.env.BASE_URL }, ); ReactDOM.createRoot(document.getElementById("root")!).render( <StrictMode> <OsdkProvider client={client}> <RouterProvider router={router} /> </OsdkProvider> </StrictMode> );

以下のルートを使用します。

  • /: アプリケーションのメインホームページです。
  • /auth/callback: OAuth 認証コールバックを処理するルートです。

認証はオントロジー SDK の OAuth クライアントを通じて管理され、未認証のユーザーは自動的にログインページにリダイレクトされます。

OAuth とオントロジー SDK クライアントの設定

OsdkProvider コンポーネント

高度な ToDo アプリケーションは、@osdk/react パッケージの OsdkProvider コンポーネントを使用して、コンポーネントツリー全体に認証コンテキストとクライアントへのアクセスを提供します。この方法は React のコンテキストパターンに従い、プロップドリリングなしで OAuth 認証とオントロジー SDK クライアントの操作を利用可能にします。

Copied!
1 2 3 4 5 6 7 8 9 10 11 import { OsdkProvider } from "@osdk/react"; import client from "./client"; // アプリケーションのルート内 ReactDOM.createRoot(document.getElementById("root")!).render( <StrictMode> <OsdkProvider client={client}> <RouterProvider router={router} /> </OsdkProvider> </StrictMode> );

認証の設定

クライアントは、以下を処理する別の client.ts ファイルで設定されます。

  1. OAuth 認証のセットアップ: オントロジー SDK の OAuth クライアントを使用して認証フローを設定します。
  2. クライアントの初期化: 認証済みユーザーのセッションでオントロジー SDK クライアントをセットアップします。
  3. 設定パラメーター: Foundry URL、クライアントID、リダイレクト URL、およびその他の OAuth パラメーターをメタタグから取得します。

OAuth クライアントは以下を処理します。

  • 認証リダイレクトフロー
  • トークンの取得と更新
  • セッション管理
  • API アクセスに適切なスコープの特定

コンポーネントでの使用

コンポーネントは、useOsdkClient フックを使用して、認証済みのオントロジー SDK クライアントにアクセスできます。

Copied!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import { useCallback } from "react"; import { useOsdkClient } from "@osdk/react"; import { OsdkITask } from "@advanced-to-do-application/sdk"; import type { IProject } from "./useProjects"; function MyComponent({ project }: { project: IProject }) { const client = useOsdkClient(); const fetchData = useCallback(async () => { const tasksPage = await client(OsdkITask).where({ projectId: { $eq: project.$primaryKey }, }).fetchPage({ $orderBy: { "dueDate": "desc", "status": "asc" }, }); // データを処理して返します }, [client, project.$primaryKey]); // コンポーネントの残りの部分 }

この使用パターンにより、以下が保証されます。

  • 認証はアプリケーションのルートで一元的に処理されます。
  • コンポーネントは、認証済みユーザーに閲覧権限があるデータにのみアクセスします。
  • OAuth トークンは自動的に更新されます。
  • API リクエストには適切な認証ヘッダーが含まれます。

アプリケーションの設定

高度な ToDo アプリケーションは設定に環境変数を使用し、開発環境と本番環境で異なる設定を使用できるようにしています。設定値は主に HTML のメタタグを通じて適用され、その後 client.ts ファイルで読み取られます。

環境ファイル

このアプリケーションは、以下の環境ファイルを使用します。

  • .env: すべての環境で使用する基本の環境変数です。
  • .env.development: 開発環境固有の変数です(npm run dev で使用)。
  • .env.production: 本番環境固有の変数です(npm run build で使用)。

index.html のメタタグの設定

このアプリケーションは、index.html のメタタグを使用して、オントロジー SDK クライアントを動的に設定します。この方法により、機密情報を JavaScript コードに直接ハードコーディングすることを避けられます。

Copied!
1 2 3 4 <meta name="osdk-clientId" content="%VITE_FOUNDRY_CLIENT_ID%" /> <meta name="osdk-redirectUrl" content="%VITE_FOUNDRY_REDIRECT_URL%" /> <meta name="osdk-foundryUrl" content="%VITE_FOUNDRY_API_URL%" /> <meta name="osdk-ontologyRid" content="%VITE_FOUNDRY_ONTOLOGY_RID%" />

メタタグの詳細

  • osdk-clientId: 認証用の OAuth クライアントIDです。
  • osdk-redirectUrl: 認証成功後のリダイレクト先 URL です。
  • osdk-foundryUrl: Foundry API のベース URL です。
  • osdk-ontologyRid: アプリケーションのオントロジーのリソース識別子です。

主要な設定変数

Copied!
1 2 3 4 5 # 認証設定 VITE_FOUNDRY_CLIENT_ID=your-client-id VITE_FOUNDRY_REDIRECT_URL=http://localhost:3000/ VITE_FOUNDRY_API_URL=https://<my-foundry-instance>.palantirfoundry.com VITE_FOUNDRY_ONTOLOGY_RID=ri.ontology.main.ontology.12345678-abcd-1234-efgh-1234567890ab

開発環境と本番環境の設定

開発環境

開発環境では、通常、以下の設定を使用します。

  • Hot Module Replacement ↗ を備えたローカル開発サーバー。
  • 開発用またはステージング用の Foundry インスタンスとの統合。

.env.development の例:

Copied!
1 2 3 4 VITE_FOUNDRY_CLIENT_ID=your-dev-client-id VITE_FOUNDRY_REDIRECT_URL=http://localhost:3000/ VITE_FOUNDRY_API_URL=https://dev-foundry.palantirfoundry.com VITE_FOUNDRY_ONTOLOGY_RID=ri.ontology.main.ontology.dev-12345

本番環境

本番環境では、以下の設定を使用します。

  • 本番用の Foundry インスタンス。
  • コードを最小化した最適化済みビルド。
  • より厳格なセキュリティ設定。

.env.production の例:

Copied!
1 2 3 4 VITE_FOUNDRY_CLIENT_ID=your-prod-client-id VITE_FOUNDRY_REDIRECT_URL=https://your-production-domain.com/ VITE_FOUNDRY_API_URL=https://prod-foundry.palantirfoundry.com VITE_FOUNDRY_ONTOLOGY_RID=ri.ontology.main.ontology.prod-67890

オントロジー SDK の主な機能

1. インターフェースとポリモーフィックなタスクタイプ

高度な ToDo アプリケーションでは、オントロジー SDK のインターフェースを使用して、次のポリモーフィックなタスクタイプを実装しています。

  • **OsdkITask:**すべてのタスクのベースインターフェース。
  • **osdkCodingTask:**コーディング関連のタスクの実装。
  • **osdkLearningTask:**メディアコンテンツを含む学習タスクの実装。
Copied!
1 2 3 4 5 6 7 // タスク詳細コンポーネントが、どの具体的な実装を表示するかを決定します if (task.osdkTask.$objectType === "osdkCodingTask") { return <TaskDetailsCoding task={task} />; } if (task.osdkTask.$objectType === "osdkLearningTask") { return <TaskDetailsLearning task={task} />; }

2. メディアコンテンツ(メディアセット)

このアプリケーションでは、メディアセットを通じてバイナリコンテンツを扱う方法を示しています。

Copied!
1 2 3 4 5 6 7 // メディアセットからメディアコンテンツを取得して表示する const response = await learningTask.mediaReference.fetchContents(); const blob: Blob | undefined = await response.blob(); const mediaUrl = blob ? URL.createObjectURL(blob) : ""; // メディアのメタデータを取得する const mediaTypeResp = await learningTask.mediaReference.fetchMetadata();

メディアの表示は、メディアの種類に基づいて動的に処理されます。

  • 埋め込みビューアーを使用した PDF ドキュメントの表示。
  • レスポンシブな画像表示。
  • プレーヤーコントロールを備えた動画の表示。
  • 外部リソースへのリンク。

3. 実行時派生プロパティ

このアプリケーションでは、実行時派生プロパティを使用して、サーバーレベルで集計統計を効率的に計算しています。

Copied!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 .withProperties({ "numberOfCodingTasks": (baseObjectSet) => baseObjectSet.pivotTo("codingTasks").aggregate("$count"), "numberOfCompletedCodingTasks": (baseObjectSet) => baseObjectSet.pivotTo("codingTasks").where({ "status": { $eq: "COMPLETED" }, }).aggregate("$count"), "numberOfLearningTasks": (baseObjectSet) => baseObjectSet.pivotTo("learningTasks").aggregate("$count"), "numberOfCompletedLearningTasks": (baseObjectSet) => baseObjectSet.pivotTo("learningTasks").where({ "status": { $eq: "COMPLETED" }, }).aggregate("$count"), // 追加の統計... })

上記の例では、次のことを示しています。

  • データ転送を最小限に抑えるために、サーバー側でメトリクスを計算する。
  • pivotTo を使用してリレーションシップをたどる。
  • where 条件で絞り込む。
  • aggregate を使用して集計する。

4. メタデータ駆動のインターフェース

このアプリケーションでは、オントロジーメタデータにアクセスし、それを使用して動的なインターフェースを作成しています。

Copied!
1 2 3 4 const getObjectTypeMetadata = useCallback(async () => { const objectTypeMetadata = await client.fetchMetadata(OsdkITask); setMetadata(objectTypeMetadata); }, [client]);

このメタデータは、次の目的で使用されます。

  • オントロジーで定義されたプロパティ名を表示する。
  • オブジェクトタイプの説明を表示する。
  • コンテキストを考慮したユーザーインターフェースを作成する。
  • コードを変更せずに、将来のオントロジーの変更に対応する。

5. 購読によるリアルタイムデータ

このアプリケーションでは、オントロジー SDK の購読を使用してリアルタイム更新を実装しています。

Copied!
1 2 3 4 5 6 7 8 9 10 const subscription = client(OsdkITask) .where({ projectId: { $eq: project.$primaryKey } }) .subscribe({ onChange(update) { // リアルタイムの更新を処理します }, onSuccessfulSubscription() { /* ... */ }, onError(err) { /* ... */ }, onOutOfDate() { /* ... */ }, });

これにより、次の利点があります。

  • タスクの作成、変更、削除時にライブ更新が行われます。
  • 変更されたデータだけを更新するため、効率的に更新できます。
  • 購読に関する問題に対してエラー処理を行えます。

6. ユーザーデータの効率的な処理

このアプリケーションでは、ユーザーデータの一括取得とキャッシュも示しています。

Copied!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 const getBatchUserDetails = useCallback(async (userIds: string[]) => { const cachedUsers: UserDetails = {}; const usersToFetch: string[] = []; userIds.forEach((userId) => { const cachedUser: State<unknown, unknown> | undefined = cache.get(`user-${userId}`); if (cachedUser && cachedUser.data) { cachedUsers[userId] = cachedUser.data as User; } else { usersToFetch.push(userId); } }); if (usersToFetch.length > 0) { const usersRequest = await getBatch(client, usersToFetch.map((userId) => ({ userId }))); Object.entries(usersRequest.data).forEach(([userId, user]) => { cachedUsers[userId] = user; mutate(`user-${userId}`, user, { revalidate: false }); }); } return cachedUsers; }, [cache, client]);

詳しくはこちら

オントロジー SDK と、このアプリケーションで使用されている高度な機能については、以下のドキュメントを参照してください。