コンテンツへスキップ
Fumadocs

createAsyncAPIPage()

AsyncAPI ドキュメントのコンテンツをレンダリングするコンポーネント

概要

Fumadocs AsyncAPI は、ページコンテンツのレンダリングに <AsyncAPIPage /> コンポーネントを使用します。このコンポーネントはクライアントコンポーネントにする必要があります。

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

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

カスタムレイアウト

オペレーションの各セクションのレイアウトをカスタマイズできます。

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>
      );
    },
  },
});
スロットレンダリング内容
headerタイトル(複数のオペレーションを含むページの場合)
connectionメッセージの方向、サーバーとチャンネルのアドレス、プレイグラウンド
descriptionオペレーションとそのチャンネルの説明、外部ドキュメント
usage選択中のサーバー向けのコードサンプル(幅の広いページではオペレーションの横に表示)
authSchemesサーバーとオペレーションのセキュリティスキーム
parametersアドレスのパラメーター、WebSocket 接続のクエリとヘッダー
messagesメッセージ(ペイロード、ヘッダー、例、相関 ID を含む)
replyリクエストに対する応答
bindings選択中のサーバーのプロトコルの詳細

メッセージの方向

AsyncAPI では、アプリケーションを send と receive のアクションで記述します。ページでは、アプリケーションとやり取りする読者の視点に合わせてこれらを反転して表示します。つまり、send は Receive、receive は Send と表示されます。サイドバーでは、スマートフォンに入る矢印またはスマートフォンから出る矢印で表されます。

プレイグラウンド

オペレーションはプレイグラウンドで試すことができます。読者はアドレスのパラメーター、クエリ、認証情報を指定して接続し、サンプルのメッセージをテキスト、16進数、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;
    // サーバーはブローカーの 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 を参照してください。

コードサンプル

各オペレーションには、選択したサーバー上でメッセージを受信・送信する方法が 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 });

プロパティ

型

各オペレーションでは、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 スキーマのレンダリング方法をカスタマイズしたり、スキーマの例の表示を無効にしたりできます。

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

export const AsyncAPIPage = createAsyncAPIPage({
  schemaUI: {
    showExample: true,
    render(options, ctx) {
      // 完全カスタムのスキーマレンダラー
      return ctx.SchemaUI(options);
    },
  },
});

TypeScript の型定義

ペイロードとヘッダーには、@fumari/json-schema-ts で生成された TypeScript の型定義をコピーするボタンがあります。

ページ上のスキーマと同様に、読者が送信するメッセージでは 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'; 

オペレーション

単一のオペレーションのUIで、チャンネル、メッセージ、バインディングを含みます。

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 スキーマを表示する 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?

最終更新日