# Fumadocs (Framework Mode, React Router): createAsyncAPI()
URL: /zh-TW/docs/react-router/integrations/asyncapi/server
Source: https://raw.githubusercontent.com/fuma-nama/fumadocs/refs/heads/main/apps/docs/content/docs/(framework)/[framework]/integrations/asyncapi/server.zh-TW.mdx

AsyncAPI 伺服器實例。

## AsyncAPI 伺服器 [#asyncapi-server]

Fumadocs AsyncAPI 的主要設定。

> 請勿在瀏覽器環境中引用此設定。

### `input` [#input]

要讀取的 AsyncAPI schema。

* 檔案路徑
* 外部 URL
* 函式 (詳見下文) 

只有列於此處的 schema 才能載入，若將其他 ID 傳入 `getSchema()`，或由頁面預先載入其他 ID，都會拋出錯誤。

<Callout type="warn">
請勿將不受信任的 schema 傳給 `input`，因為其中的 `$ref` 能讀取本機檔案並擷取任意 URL，連私有主機也不例外。
</Callout>

```ts tab="Basic"
import { createAsyncAPI } from '@fumadocs/asyncapi/server';

export const asyncapi = createAsyncAPI({
  input: ['./streetlights.yaml'],
});
```

```ts tab="Functions"
import { createAsyncAPI } from '@fumadocs/asyncapi/server';

export const asyncapi = createAsyncAPI({
  input: {
    // [id]：下載後的 AsyncAPI schema
    galaxy: async () => {
      const res = await fetch('https://example.com/asyncapi.yaml');
      return res.text();
    },
  },
});
```

### `disableCache` [#disablecache]

停用已載入 schema 的快取。適合在開發階段 schema 頻繁變動時使用。

```ts
import { createAsyncAPI } from '@fumadocs/asyncapi/server';

export const asyncapi = createAsyncAPI({
  input: ['./asyncapi.yaml'],
  disableCache: true,
});
```

## 只載入一次文件 [#loading-documents-once]

頁面會透過 props 接收完整的文件，因此每次載入頁面、導覽或預先擷取時，都會再傳送一次文件。若文件較大，建議不要透過 props 傳遞：

```ts title="lib/asyncapi.ts"
import { createAsyncAPI } from '@fumadocs/asyncapi/server';

export const asyncapi = createAsyncAPI({
  // ID 最終會出現在 URL 中，請確保可安全用於 URL
  input: { streetlights: './streetlights.yaml' },
  includeDocument: false, // [!code ++]
});
```

傳入 `loadDocument`，即可讓每份文件在每個瀏覽器工作階段中只載入一次。此函式也會在伺服器端算繪期間執行：

```tsx title="components/api-page.tsx"
'use client';
import { preload } from 'react-dom';
import { createAsyncAPIPage } from '@fumadocs/asyncapi/ui';

export const AsyncAPIPage = createAsyncAPIPage({
  async loadDocument(id) {
    if (import.meta.env.SSR) {
      // 瀏覽器會在載入頁面時一併開始下載
      preload(`/api/asyncapi/${id}`, { as: 'fetch', crossOrigin: 'anonymous' });
      const { asyncapi } = await import('@/lib/asyncapi');
      return (await asyncapi.getSchema(id)).bundled;
    }
    return (await fetch(`/api/asyncapi/${id}`)).json();
  },
});
```

透過路由將文件提供給瀏覽器：

```ts tab="app/routes/asyncapi.ts"
import type { Route } from './+types/asyncapi';
import { asyncapi } from '@/lib/asyncapi';

export async function loader({ params }: Route.LoaderArgs) {
  return Response.json((await asyncapi.getSchema(params.id)).bundled);
}
```

```ts tab="app/routes.ts"
import { route, type RouteConfig } from '@react-router/dev/routes';

export default [
  // [!code ++]
  route('api/asyncapi/:id', 'routes/asyncapi.ts'),
  // ...
] satisfies RouteConfig;
```

* `loadDocument` 同樣適用於產生的 MDX 檔案。
* 若使用[由 Fumadocs CLI 安裝的 UI](/docs/react-router/integrations/asyncapi/api-page#full-ui)，請將 `loadDocument` 傳入 `createAsyncAPIRenderer()`。
* 瀏覽器會保留每份文件，直到頁面重新載入為止。使用 [`disableCache`](#disablecache) 時，請保持開啟 `includeDocument`。