React Router v7 已發布。 查看文件
API 路由

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 會執行 fetch 到伺服器,以從 loader 取得資料並呈現路由。將資料載入元件的整個任務都已處理完畢。您不需要 API 路由來滿足路由元件的資料需求,它們已經是它們自己的 API。

在導覽之外呼叫 Loader

然而,有時您想從 loader 取得資料,但不是因為使用者正在訪問路由,而是因為目前的頁面由於某些原因需要該路由的資料。一個非常清楚的例子是 <Combobox> 元件,它會查詢資料庫以取得記錄並向使用者建議它們。

您可以使用 useFetcher 來處理這種情況。再次,由於瀏覽器中的 Remix 知道伺服器上的 Remix,因此您不必費力取得資料。Remix 的錯誤處理會啟動,並且也會為您處理競爭條件、中斷和 fetch 取消。

例如,您可以有一個路由來處理搜尋

export async function loader({
  request,
}: LoaderFunctionArgs) {
  const url = new URL(request.url);
  return json(
    await searchCities(url.searchParams.get("q"))
  );
}

然後將 useFetcher 與 Reach UI 的 combobox 輸入一起使用

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>Failed to load cities :(</p>
            ) : cities.data.length ? (
              <ComboboxList>
                {cities.data.map((city) => (
                  <ComboboxOption
                    key={city.id}
                    value={city.name}
                  />
                ))}
              </ComboboxList>
            ) : (
              <span>No results found</span>
            )}
          </ComboboxPopover>
        ) : null}
      </Combobox>
    </cities.Form>
  );
}

資源路由

在其他情況下,您可能需要屬於您的應用程式一部分,但不屬於應用程式 UI 一部分的路由。也許您想要一個 loader 將報表呈現為 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 呼叫,則會傳回 loader 的回應。如果使用 POSTPUTPATCHDELETE 呼叫,則會傳回 action 的回應。

以下是一些用例,可讓您開始思考。

  • 用於行動應用程式的 JSON API,它與 Remix UI 重複使用伺服器端程式碼
  • 動態產生 PDF
  • 為部落格文章或其他頁面動態產生社群圖片
  • 其他服務的 Webhook

您可以在資源路由文件中閱讀更多內容。

文件和範例依據授權 MIT