AsyncAPIでWebSocketモックサーバーを作りたいと思ったそこのあなたへ

### 🌟 はじめに 🌟
バックエンドが未完成でも、リアルタイム通信を使ったWebSocketの開発を進めたくないですか？  
そんな時に役立つのが、**AsyncAPI**を使ったモックサーバーです！  
この記事では、**WebSocketモックサーバー**を簡単に作成する方法を楽しく解説します🎉

---

### **AsyncAPIって何？🤔**
- **APIの非同期通信を設計するための標準仕様**  
  - HTTP用の**OpenAPI**に対する、WebSocket用の**AsyncAPI**。
  - 非同期通信の仕様をコードに落とし込みやすく、開発がスムーズに🚀。

---

### セットアップ方法 🛠️

まずは以下のリポジトリをcloneして、準備を始めましょう！
ローカルでモックサーバーを作成するのが大変だったため、
dockerを使用して、いつでも簡単に作成できるようにしました。

https://github.com/kaaaaakun/AsyncAPI-mock-server/tree/main

#### Makefileのコマンド説明 🎮

##### モックサーバーの初期化 🔧

`mock-init` ターゲットを実行すると、以下の処理が行われます：
- `./mock-server` ディレクトリがなければ作成
- **AsyncAPI Generator**のDockerイメージをビルド
- `asyncapi.yaml`に基づいてWebSocketモックサーバーを生成
- 生成されたサーバーを `./mock-server` に保存

```bash
make mock-init
```

##### モックサーバーの起動 🚀

`mock-start` ターゲットで、以下のことが行われます：
- `./mock-server`ディレクトリからモックサーバー用のDockerイメージをビルド
- サーバーをポート3000で起動（アクセスURL：`http://localhost:3000`）
- `wscat -c ws://localhost:3000/` でWebSocket接続を確認

```bash
make mock-start
```

##### モックサーバーのクリーンアップ 🧹

`mock-clean`ターゲットで、モックサーバーのデータをきれいに削除できます。

```bash
make mock-clean
```

---

### プロジェクト構造 📁

- **`Dockerfile`**: AsyncAPI Generator とモックサーバーのイメージをビルド
- **`asyncapi.yaml`**: WebSocket チャットサービスの仕様
- **`Makefile`**: 実行コマンドを管理（`mock-init`, `mock-start`, `mock-clean`）

---

##### Dockerfile 🐳

`Dockerfile`では、AsyncAPI Generatorとモックサーバーを構築します。手順は以下の通りです：
- 必要な依存パッケージ（`@asyncapi/generator`と`@asyncapi/cli`）をインストール
- `asyncapi.yaml`を基にモックサーバーを生成
- 生成されたサーバー用のDockerfileでは、ベースイメージを`node:18-alpine`に変更

##### asyncapi.yaml 📄

AsyncAPIの仕様ファイルで、WebSocketチャットサービスを定義しています。サポートする操作は以下の通り：

下記、特に注意する点⚠️
- `operationId`は必須 
- versionは`3.0.0`未満を使用 
- `servers`の`websocketServer`部分は変更しないでください 

```yaml
asyncapi: '2.6.0'
info:
  title: WebSocket Mock Example
  version: '1.0.0'
servers:
  websocketServer:
    url: ws://localhost:3000
    protocol: ws
channels:
  chat/message:
    subscribe:
      operationId: receiveMessage
      message:
        payload:
          type: object
          properties:
            user:
              type: string
            message:
              type: string
    publish:
      operationId: sendMessage
      message:
        payload:
          type: object
          properties:
            user:
              type: string
            message:
              type: string
```

---

### モックサーバー実装部分の変更 ✏️

`mock-server/src/api/services/`内のコードを自分でカスタマイズしましょう！  
以下は、受信および送信の自動生成コードです💬

```js
const service = module.exports = {};

/**
 * 
 * @param {object} ws WebSocket connection.
 */
service.receiveMessage = async (ws) => {
  ws.send('Message from the server: Implement here your business logic that sends messages to a client after it connects.');
};
/**
 * 
 * @param {object} ws WebSocket connection.
 * @param {object} options
 * @param {string} options.path The path in which the message was received.
 * @param {object} options.query The query parameters used when connecting to the server.
 * @param {object} options.message The received message.
 * @param {string} options.message.payload.user
 * @param {string} options.message.payload.message
 */
service.sendMessage = async (ws, { message, path, query }) => {
  ws.send('Message from the server: Implement here your business logic that reacts on messages sent from a client.');
};

```

---

### **まとめ 🌈**  

AsyncAPIを使うと、  
- WebSocketモックサーバーを簡単に立ち上げられる！  
- 非同期通信の開発が効率的に進められる！  
- ドキュメントと実装の一貫性が保たれる！  

WebSocket開発でお困りの方、ぜひAsyncAPIを試してみてくださいね！🌟