🦓

[Rails]APIモード+Reactでrails newする

2023/10/05に公開

はじめに

Rails APIモード+Reactでrails newしてみました。

  • APIモードを使用すると、バックエンドとフロントエンドを独立して開発できます。RailsがwebアプリのバックエンドとしてAPIを提供することに特化したアプリを作成できます。
  • APIモードでは、通常のHTMLビューを生成する必要がなく、代わりにJSONやXMLなどのデータフォーマットを使用してクライアントにデータを提供します。
  • APIモードでは、セキュリティが重要です。認証、認可、CSRF(クロスサイトリクエストフォージェリ)対策などのセキュリティ機能を適切に実装する必要があります。

環境

Rails 7.0.8
Ruby 3.2.1
Vite

tl;dr

  1. --apiオプションを使ってrails newする
  2. CORS関連の設定
  3. scaffoldでPostモデルを作成する
  4. APIエンドポイントを指定する
  5. Viteアプリを作成する

rails new

➜  rails_api rails new . --api
       exist  
      create  README.md
      create  Rakefile
      create  .ruby-version
      create  config.ru
      create  .gitignore
      create  .gitattributes
      create  Gemfile
         run  git init from "."
...

gemをインストールする

Gemfileの36行目あたりの内容をアンコメントし、gemをインストールします。

# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible
gem "rack-cors"
bundle install

rack-corsは、RailsでCORS(Cross-Origin Resource Sharing)ポリシーを管理するためのミドルウェアです。
CORSは、異なるオリジン(ドメイン、プロトコル、ポート)からのリクエストを許可または拒否するためのセキュリティメカニズムであり、Webアプリケーションのセキュリティを強化するために使用されます。

https://github.com/cyu/rack-cors

CORS対策

config/initializers/cors.rbにあるコードブロックのコメントも解除します。

Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
   # ローカル
    origins "http://127.0.0.1:5173"
    # 全てのオリジンを許可する
    origins '*'
    # ドメインを許可する
    origins 'https://domain.com'

    resource "*",
      headers: :any,
      methods: [:get, :post, :put, :patch, :delete, :options, :head]
  end
end

デフォルトの設定は、example.comからのリクエストを全てのパスへのHTTPメソッドとして指定されたもの以外のリクエストから拒否します。

scaffoldでPostモデルを作成する

bin/rails g scaffold Post title body:text
bin/rails db:migrate

Fakerを使ってダミー投稿を作成します。

db/seeds.rb
20.times do
    Post.create(
        title: Faker::Lorem.sentence(word_count: 3),
        body: Faker::Lorem.paragraph(sentence_count: 3)
    )
end

http://localhost:3000/postsにアクセスし、投稿がJSON形式で表示されていることを確認します。

APIエンドポイントを指定する

routes.rbにAPI用ルートを追加する

config/routes.rb
Rails.application.routes.draw do
  namespace :api do
    namespace :v1 do
      resources :posts
    end
  end
end

/api/v1/postsエンドポイントに対するAPIエンドポイントを設定します。

namespace :api: API関連のエンドポイントが/apiの下にまとめられます。
namespace :v1: APIのバージョン1(v1)のエンドポイントが/api/v1の下にまとめられます。バージョン管理を行う際に、新しいバージョンを追加することもできます(例:namespace :v2)。

こちらの設定によって、次のようなAPIエンドポイントが作成されます:

  • GET /api/v1/posts: すべての投稿を取得するためのエンドポイント。
  • GET /api/v1/posts/:id: 特定の投稿を取得するためのエンドポイント。
  • POST /api/v1/posts: 新しい投稿を作成するためのエンドポイント。
  • PUT /api/v1/posts/:id: 特定の投稿を更新するためのエンドポイント。
  • DELETE /api/v1/posts/:id: 特定の投稿を削除するためのエンドポイント。

コントローラーにネームスペースを設定する

ルーティングとコントローラーのネームスペースを一致させることが推奨されるのでコントローラーもネームスペースを設定します。

1. controllers/のディレクトリ内に、api/フォルダを作成し、更にその中にv1/フォルダーを作成します。
posts_controller.rbcontrollers/api/v1/内に移動します。

2. Postsコントローラーにネームスペースを追加します。

app/controllers/api/v1/posts_controller.rb
class Api::V1::PostsController < ApplicationController
...
end

http://localhost:3000/api/v1/postsにアクセスし、投稿がJSON形式で表示されていることを確認します。

Viteアプリを作成する

npm create vite@latest
Need to install the following packages:
  create-vite@latest
Ok to proceed? (y) y
✔ Project name: … client
✔ Select a framework: › React
✔ Select a variant: › JavaScript

Scaffolding project in /Users/***/workspace/rails_api/client...

Done. Now run:

  cd client
  npm install
  npm run dev

client/ディレクトリ内に移動します。
dependenciesをインストールします。

npm install

added 267 packages, and audited 268 packages in 14s

96 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

初期のclient/フォルダー:

dotenvをインストールする

APIのエンドポイントを環境変数に設定をするためにdotenvをインストールします。

npm install dotenv

added 1 package, and audited 269 packages in 665ms

97 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

エンドポイントのURLを指定します。
こちらのファイルを.gitignoreに追加しましょう。

client/.env.development
VITE_API_URL = http://localhost:3000/api/v1/posts

フロントのサーバーを起動します。

npm run dev

  VITE v4.4.11  ready in 410 ms

  ➜  Local:   http://127.0.0.1:5173/
  ➜  Network: use --host to expose
  ➜  press h to show help

http://127.0.0.1:5173/にアクセスします。
以下の画面が表示されたらOKです。

終わりに

APIモード+Reactでrails newしてみました。
https://vitejs.dev/guide/
https://railsguides.jp/api_app.html

Discussion