APIルート
サーバー上で実行されない、あるいはほとんど実行されないReactアプリケーションを構築することに慣れているかもしれません。そのような場合、アプリケーションはAPIルートのセットによってサポートされています。Remixでは、ほとんどのルートがUIとAPIの両方を兼ねており、ブラウザ上のRemixはサーバー上の自身と通信する方法を知っています。
一般的に、「APIルート」という概念は全く必要ありません。しかし、この用語に興味を持つことは分かっているので、ここで説明します!
ルートは独自のAPIを持つ
以下のルートを考えてみましょう:
export async function loader() { return json(await getTeams());}
export default function Teams() { return ( <TeamsView teams={useLoaderData<typeof loader>()} /> );}
ユーザーが<Link to="/teams" />
へのリンクをクリックするたびに、ブラウザ上のRemixはサーバーへのフェッチを実行し、loader
からデータを取得してルートをレンダリングします。コンポーネントへのデータ読み込みのタスク全体が完了しています。ルートコンポーネントのデータ要件を満たすためにAPIルートは必要ありません。ルート自体が既に独自のAPIとなっています。
ナビゲーション以外でのローダーの呼び出し
しかし、ユーザーがそのルートを訪れているわけではなく、現在のページが何らかの理由でそのルートのデータを必要としているため、ローダーからデータを取得したい場合があります。明確な例として、データベースからレコードを検索してユーザーに推薦する<Combobox>
コンポーネントがあります。
このような場合には、useFetcher
を使用できます。ブラウザ上のRemixはサーバー上のRemixと通信する方法を知っているため、データを取得するために多くの作業は必要ありません。Remixのエラー処理が機能し、競合状態、中断、フェッチのキャンセルも自動的に処理されます。
例えば、検索を処理するルートを以下のように作成できます:
export async function loader({ request,}: LoaderFunctionArgs) { const url = new URL(request.url); return json( await searchCities(url.searchParams.get("q")) );}
そして、Reach UIのコンボボックス入力とuseFetcher
を組み合わせて使用します:
function CitySearchCombobox() { const cities = useFetcher();
return ( <cities.Form method="get" action="/city-search"> <Combobox aria-label="Cities"> <div> <ComboboxInput name="q" onChange={(event) => cities.submit(event.target.form) } /> {cities.state === "submitting" ? ( <Spinner /> ) : null} </div>
{cities.data ? ( <ComboboxPopover className="shadow-popup"> {cities.data.error ? ( <p>都市の読み込みに失敗しました :(</p> ) : cities.data.length ? ( <ComboboxList> {cities.data.map((city) => ( <ComboboxOption key={city.id} value={city.name} /> ))} </ComboboxList> ) : ( <span>結果が見つかりません</span> )} </ComboboxPopover> ) : null} </Combobox> </cities.Form> );}
リソースルート
他の場合には、アプリケーションの一部ではあるものの、アプリケーションのUIの一部ではないルートが必要になることがあります。例えば、レポートをPDFとしてレンダリングするローダーが必要かもしれません:
export async function loader({ params,}: LoaderFunctionArgs) { const report = await getReport(params.id); const pdf = await generateReportPDF(report); return new Response(pdf, { status: 200, headers: { "Content-Type": "application/pdf", }, });}
ルートがRemix UI(<Link>
やuseFetcher
など)によって呼び出されず、デフォルトのコンポーネントをエクスポートしていない場合、それは汎用のリソースルートとなります。GET
で呼び出された場合はローダーのレスポンスを返し、POST
、PUT
、PATCH
、DELETE
で呼び出された場合はアクションのレスポンスを返します。
以下に、考えられるユースケースをいくつか示します:
- モバイルアプリケーション用のJSON API(サーバーサイドコードをRemix UIで再利用)
- 動的なPDFの生成
- ブログ記事やその他のページ用のソーシャル画像の動的生成
- 他のサービス用のWebhook
詳細はリソースルートのドキュメントをご覧ください。