跳至內容
Fumadocs

createAsyncAPIPage()

用於算繪 AsyncAPI 文件內容的元件

概覽

Fumadocs AsyncAPI 使用 <AsyncAPIPage /> 元件算繪頁面內容,此元件應為用戶端元件。

components/api-page.tsx
'use client';
import { createAsyncAPIPage } from '@fumadocs/asyncapi/ui';

export const AsyncAPIPage = createAsyncAPIPage({
  // 設定
});

自訂版面配置

您可以自訂 operation 中各個區塊的版面配置方式。

components/api-page.tsx
'use client';
import { createAsyncAPIPage } from '@fumadocs/asyncapi/ui';

export const AsyncAPIPage = createAsyncAPIPage({
  content: {
    renderOperationLayout(slots) {
      return (
        <div className="flex flex-col gap-6">
          {slots.header}
          {slots.connection}
          {slots.description}
          {slots.parameters}
          {slots.messages}
        </div>
      );
    },
  },
});
Slot算繪內容
header標題,用於包含多個 operation 的頁面
connection訊息的傳遞方向、伺服器與頻道位址,以及互動測試區
descriptionoperation 及其頻道的描述,以及外部文件
usage所選伺服器的程式碼範例,在寬版頁面中會顯示於 operation 旁邊
authSchemes伺服器與 operation 的安全性方案
parameters位址參數,以及 WebSocket 連線的查詢參數與標頭
messages訊息,包含其酬載、標頭、範例與 correlation ID
reply請求的回覆
bindings所選伺服器的協定細節

訊息的方向

AsyncAPI 以 send 與 receive 動作來描述應用程式。由於讀者是與該應用程式通訊的一方,頁面會將兩者對調呈現:send 顯示為 Receive,receive 則顯示為 Send。側邊欄會以指向手機或從手機向外的箭頭來表示兩者。

互動測試區

您可以在互動測試區中試用各個 operation:讀者可透過位址參數、查詢字串與認證資訊建立連線,將範例中的訊息以文字、十六進位或 Base64 格式送出,並查看接收到的訊息。

各協定的伺服器皆透過傳輸層連線,並已內建支援 WebSocket (ws 與 wss) 。

components/api-page.tsx
'use client';
import { createAsyncAPIPage } from '@fumadocs/asyncapi/ui';
import { sseTransport } from '@fumadocs/asyncapi/playground';

export const AsyncAPIPage = createAsyncAPIPage({
  playground: {
    // 依伺服器的協定對應
    transports: { http: sseTransport, https: sseTransport },
    // 設為 `false` 即可停用互動測試區
    enabled: true,
  },
});

瀏覽器限制

瀏覽器無法在 WebSocket 連線中傳送其他網站的標頭或 Cookie,僅支援透過查詢參數提供的認證資訊。 透過 HTTPS 提供的頁面只能連線至 wss 伺服器。

Server-Sent Events

sseTransport 會透過 fetch 接收 http 與 https 伺服器的事件,但讀者無法透過它傳送訊息。

  • API 金鑰會放在標頭或查詢字串中傳送。
  • HTTP bearer 與 basic 認證資訊會透過 Authorization 標頭傳送。

此功能需要手動啟用,因為 webhook 同樣使用 http 伺服器。

自訂傳輸層

傳輸層負責連線至伺服器,並透過 events 回報連線期間發生的狀況。以下範例使用 MQTT.js,透過 WebSocket 傳送 MQTT:

lib/mqtt-transport.ts
import mqtt from 'mqtt';
import type { PlaygroundTransport } from '@fumadocs/asyncapi/playground';

export const mqttTransport: PlaygroundTransport = {
  // 此傳輸層適用的安全性方案,會成為互動測試區的輸入欄位
  auth: (scheme) => scheme.type === 'userPassword',
  connect({ url, address, auth }, events) {
    const credentials = auth[0]?.value;
    // 伺服器為 broker 的 WebSocket 監聽器,例如 `localhost:9001`
    const client = mqtt.connect(`ws://${new URL(url).host}`, {
      ...(typeof credentials === 'object' && credentials),
      reconnectPeriod: 0,
    });

    client.on('connect', () =>
      client.subscribe(address, (error) => (error ? events.error(error.message) : events.open())),
    );
    client.on('message', (_topic, payload) => events.message(payload.toString()));
    client.on('error', (error) => events.error(error.message));
    client.on('close', () => events.close());

    return {
      send: (data) =>
        client.publish(address, typeof data === 'string' ? data : (new Uint8Array(data) as Buffer)),
      close: () => client.end(),
    };
  },
};
components/api-page.tsx
'use client';
import { createAsyncAPIPage } from '@fumadocs/asyncapi/ui';
import { mqttTransport } from '@/lib/mqtt-transport';

export const AsyncAPIPage = createAsyncAPIPage({
  playground: {
    transports: { mqtt: mqttTransport },
  },
});

詳細資訊請參閱 PlaygroundTransport。

程式碼範例

每個 operation 都會以 JavaScript 和 Python 示範如何在所選伺服器上接收或傳送其訊息。

協定JavaScriptPython
ws, wssWebSocketwebsockets
mqtt, mqtts, secure-mqttmqttpaho-mqtt
kafka, kafka-securekafkajsconfluent-kafka
amqp, amqpsamqplibpika
nats@nats-io/transport-nodenats-py

您可以透過 codeUsages 新增產生器,或取代預設的產生器:

components/api-page.tsx
'use client';
import {
  createAsyncAPIPage,
  createCodeUsageGeneratorRegistry,
  registerDefaultCodeUsages,
} from '@fumadocs/asyncapi/ui';

// 若要從頭開始,請省略預設項目
const codeUsages = registerDefaultCodeUsages(createCodeUsageGeneratorRegistry());

codeUsages.add('websocat', {
  label: 'websocat',
  lang: 'bash',
  // `url` 是用來連線至 WebSocket 頻道的 URL
  generate({ protocol }, { url }) {
    // 使用其他協定時隱藏
    if (protocol !== 'ws' && protocol !== 'wss') return '';
    return `websocat "${url}"`;
  },
});

export const AsyncAPIPage = createAsyncAPIPage({ codeUsages });

屬性

型別

每個 operation 都可以在 x-codeSamples 中定義自己的範例,這些範例會取代相同 lang 的自動產生範例;若設定 source: false,則會移除該範例。

operations:
  receiveLightMeasurement:
    action: receive
    x-codeSamples:
      - lang: js
        label: SDK
        source: |
          lights.onMeasured((event) => console.log(event));
      - lang: python
        source: false

結構描述 UI

自訂 JSON schema 的算繪方式,或停用 schema 範例。

components/api-page.tsx
'use client';
import { createAsyncAPIPage } from '@fumadocs/asyncapi/ui';

export const AsyncAPIPage = createAsyncAPIPage({
  schemaUI: {
    showExample: true,
    render(options, ctx) {
      // 完全自訂的 schema 算繪器
      return ctx.SchemaUI(options);
    },
  },
});

TypeScript 定義

酬載與標頭都附有按鈕,可複製其 TypeScript 定義,這些定義由 @fumari/json-schema-ts 產生。

與頁面上的 schema 一樣,這些定義會省略讀者所傳送訊息中的 readOnly 屬性,以及讀者所接收訊息中的 writeOnly 屬性。

components/api-page.tsx
'use client';
import { createAsyncAPIPage } from '@fumadocs/asyncapi/ui';

export const AsyncAPIPage = createAsyncAPIPage({
  // 或使用 `(schema, ctx) => string | undefined` 自行產生定義
  generateTypeScriptDefinitions: false,
});

國際化

假設您已在 UI 層級設定好國際化:

layout.shared.tsx
import { defineI18n } from 'fumadocs-core/i18n';
import { uiTranslations } from 'fumadocs-ui/i18n';
import { asyncapiTranslations } from '@fumadocs/asyncapi/i18n';

const i18n = defineI18n({
  languages: ['en', 'cn'],
  defaultLanguage: 'en',
});

export const translations = i18n
  .translations()
  .extend(uiTranslations())
  .extend(asyncapiTranslations())
  .add({
    cn: {
      displayName: 'Chinese',
      'Messages(operation page)': '消息',
    },
  });

詳細資訊請參閱翻譯。

語法突顯

AsyncAPI 頁面會使用 Shiki 為程式碼區塊進行語法突顯,如需自訂,請傳入語法突顯器。

components/api-page.tsx
'use client';
import { createAsyncAPIPage } from '@fumadocs/asyncapi/ui';
import { highlighter } from '@/lib/highlighter';

export const AsyncAPIPage = createAsyncAPIPage({ highlighter });

自訂元件

覆寫預設的標題與程式碼區塊元件。

components/api-page.tsx
'use client';
import { createAsyncAPIPage } from '@fumadocs/asyncapi/ui';

export const AsyncAPIPage = createAsyncAPIPage({
  components: {
    Heading({ id, depth, ...props }) {
      const Tag = `h${depth}` as const;
      return <Tag id={id} {...props} />;
    },
    CodeBlock({ lang, code }) {
      return <pre data-lang={lang}>{code}</pre>;
    },
  },
});

自訂 UI

若現有選項無法滿足您的自訂需求,您可以透過 Fumadocs CLI 將 UI 安裝到您的程式碼庫中。

完整 UI

API 頁面的完整 UI,建構在無頭式層之上。

npx @fumadocs/cli add asyncapi/page

它會自行安裝 <AsyncAPIPage />,因此不再需要 components/api-page.tsx。請更新 <AsyncAPIPage /> 的匯入路徑:

import { AsyncAPIPage } from '@/components/api-page'; 
import { AsyncAPIPage } from '@/components/asyncapi/page'; 

Operation

單一 operation 的 UI,包括其頻道、訊息與繫結 (bindings) 。

npx @fumadocs/cli add asyncapi/operation

互動測試區

互動測試區,以 usePlayground() 為基礎建構。

npx @fumadocs/cli add asyncapi/playground
components/api-page.tsx
'use client';
import { createAsyncAPIPage } from '@fumadocs/asyncapi/ui';
import { Operation } from '@/components/asyncapi/operation';

export const AsyncAPIPage = createAsyncAPIPage({
  components: {
    Operation,
  },
});

結構描述 UI

用於呈現 JSON schema 的 UI,與其他 API 整合共用。其狀態來自 <SchemaUIProvider />。

npx @fumadocs/cli add api-docs/schema
components/api-page.tsx
'use client';
import { createAsyncAPIPage } from '@fumadocs/asyncapi/ui';
import { Schema } from '@/components/api/schema';

export const AsyncAPIPage = createAsyncAPIPage({
  components: {
    SchemaUI: Schema,
  },
});

How is this guide?

最後更新於