跳转到内容

API 路由

您可能习惯于构建不在服务器上运行的 React 应用,或者至少很少在服务器上运行,因此它由一组 API 路由支持。在 Remix 中,您的大多数路由都是您的 UI 和 API,因此浏览器中的 Remix 知道如何在服务器上与自己对话。

一般来说,你根本不需要 API 路由这个概念。但我们知道你会对这个术语感兴趣,所以我们就在这里!

路由有自己的 API

考虑这条路由:

app/routes/teams.tsx
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 的错误处理功能会启动,竞争条件、中断和提取取消也会为您处理。

例如,您可以有一条路由来处理搜索:

app/routes/city-search.tsx
export async function loader({
request,
}: LoaderFunctionArgs) {
const url = new URL(request.url);
return json(
await searchCities(url.searchParams.get("q"))
);
}

然后将 useFetcher 与 Reach UI 的组合框输入一起使用:

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 的路由。也许您想要一个将报告呈现为 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 调用,则返回加载器的响应。如果使用 POSTPUTPATCHDELETE 调用,则返回操作的响应。

以下列出一些可供您思考的用例。

  • 适用于移动应用的 JSON API,该应用通过 Remix UI 重用服务器端代码
  • 动态生成 PDF
  • 动态生成博客文章或其他页面的社交图像
  • 适用于其他服务的 Webhook

您可以在资源路由文档中阅读更多内容。