Rails 7 と Vue.js 3 を使用したモノリシックアプリケーションにおけるAPI通信について

## はじめに
Rails 7とVue.js 3を組み合わせたモノリシックアプリケーション開発では、API通信の必要性がしばしば生じます。ここでは、API通信が必要となる状況と、その設定方法について説明します。

## 1. API通信について

### 1-1. api/tasks(tasksの部分はTaskモデルに関連するビュー名)とは:
`api/tasks`は、Vue.jsなどのフロントエンドフレームワークから非同期にアクセスするためのAPIエンドポイントで、フロントエンドとバックエンがJSON形式でやり取りする際に使用します。モノリシックアプリケーションにおいても、フロントエンドで動的なデータ操作（例: タスクのドラッグ&ドロップ）が発生する場合、バックエンドとの非同期通信が必要になり、そのためにAPIエンドポイントを設定する必要があります。

### 1-2. 非同期通信の例:
静的なページの表示や簡単な動作（文字の表示・非表示など）ではAPI通信は不要です。しかし、ユーザーの操作によってデータベースに変更を加える必要がある場合（例: タスクの移動や更新）、非同期通信によるAPIの利用が必須となります。

### 1-3. ビューの分離:
モノリシックアプリケーション内で、API通信を伴うビューとそうでないビューは、特定のディレクトリ構造に従って分離する必要はありません。重要なのは、API通信を行う部分（主にフロントエンドのJavaScriptやVueコンポーネント）と、サーバーサイドで完結するビュー（Railsのビューファイル）を適切に統合することです。

### 1-4. APIディレクトリの役割:
`app/controllers/api`ディレクトリは、**フロントエンドからの非同期リクエストを処理するためのAPIコントローラを格納**します。このディレクトリ内のコントローラは、JSON形式でデータを返すことに特化しています。Vue.jsからのリクエストを受け、データベースの操作結果をフロントエンドに送信する役割を担います。

### 1-5. APIディレクトリの設定:
モノリシックアプリケーションにおいても、`controllers/api`ディレクトリを使用するのはAPIコントローラのみです。モデル(`app/models`)、ビュー(`app/views`)、およびフロントエンドのJavaScript(`app/javascript`)は、API通信の有無に関わらずそのままで問題ありません。`tasks_controller.rb`のようなコントローラは、API通信と非API通信の両方に対応するため、それぞれ適切なディレクトリに配置し、ロジックを分離して管理します。

### ここまでのまとめ

モノリシックアプリケーションにおいてAPI通信が必要となるのは、フロントエンドからの非同期リクエストをサーバーサイドで処理する必要がある場合です。APIエンドポイントの設定は、このような非同期通信を実現するために不可欠です。一方、API通信を必要としないビューや機能では、従来通りのRailsのビューとコントローラの設定で十分です。


## 2. 非API通信とAPI通信の統合

モノリシックアプリケーションにおける非API通信（通常のRailsビュー）とAPI通信（Vue.jsコンポーネントからの非同期リクエスト）の統合は、現代のウェブ開発においてよく見られるアプローチです。この方法により、アプリケーションは伝統的なRailsの強みと、SPA（Single Page Application）のリッチなユーザーインタラクションを組み合わせることができます。

### 2-1. 実装例

タスク管理機能の実装において、タスクのドラッグ＆ドロップ機能をVue.jsで実現し、その結果をRailsのAPIを通じてデータベースに反映させる例を考えます。

### 2-2. フロントエンド（Vue.js）

`DraggableCalendar.vue` コンポーネントでは、各タスクがドラッグ＆ドロップされた際のイベントをハンドルし、その新しい位置（日付）をサーバーに送信する必要があります。

```javascript
methods: {
  // タスクをドラッグ開始した時の処理
  dragStart(event, task) {
    event.dataTransfer.setData('task', JSON.stringify(task));
  },
  // タスクをドロップした時の処理
  drop(event, day) {
    const task = JSON.parse(event.dataTransfer.getData('task'));
    axios.post(`/api/tasks/${task.id}/move`, { new_day: day })
      .then(response => {
        // タスクの移動が成功した場合の処理
      })
      .catch(error => {
        // エラー処理
      });
  },
}
```

### 2-3. バックエンド（Rails）

`app/controllers/api/tasks_controller.rb` で、タスクの移動を処理するアクションを定義します。

```ruby
module Api
  class TasksController < ApplicationController
    def move
      @task = Task.find(params[:id])
      if @task.update(day: params[:new_day])
        render json: @task
      else
        render json: @task.errors, status: :unprocessable_entity
      end
    end
  end
end
```

### 2-3.`config/routes.rb` 

```ruby
namespace :api do # ルートを追加
  resources :tasks do
    member do
      post 'move'
    end
  end
end
```

### 2-4. セキュリティとパフォーマンス

APIを介したデータのやり取りでは、セキュリティ（認証・認可）とパフォーマンス（適切なインデックスの使用、不要なデータの取得を避ける）に注意する必要があります。例えば、JWT（JSON Web Tokens）やRailsの`has_secure_token`を使用したAPI認証や、Active Recordクエリの最適化などが考えられます。

### ここまでのまとめ

RailsとVue.jsを組み合わせたモノリシックアプリケーション開発では、静的なコンテンツの提供と動的なデータ操作を柔軟に統合することができます。API通信を適切に設計し、フロントエンドとバックエンドの連携を確実に行うことで、ユーザーフレンドリーでインタラクティブなウェブアプリケーションを実現できます。

## 参考記事
https://qiita.com/KM9973/items/1857ceda646102761298