Chapter 04無料公開

【Rails】APIモードで環境構築

のら
のら
2022.06.30に更新

Railsで新規プロジェクトを作成する

早速、Railsで新規プロジェクトを作成していきます。モノリスのRailsが有名ですが、今回はAPIモードでRailsプロジェクトを構築していきます。

そもそもAPIって?

「そんなこといいから早くアプリ作っていこうぜ!」という人は、ここは飛ばしてください。しかし、一応読んでおいたほうが理解が深くなると思いますので、読んでいただけるとありがたいです🙇‍♂️

APIとは 「Application Programming Interface」 の略です。
Railsガイドでは下記のように説明されています。

1 APIアプリケーションについて
従来、Railsの「API」というと、プログラムからアクセスできるAPIをWebアプリケーションに追加することを指すのが通例でした。たとえば、GitHubが提供するAPI をカスタムクライアントから利用できます。
近年、さまざまなクライアント側フレームワークが登場したことによって、Railsで作ったバックエンドサーバ―を、他のWebアプリケーションとネイティブアプリケーションの間で共有する手法が増えてきました。
たとえば、Twitterは自社のWebアプリケーションで パブリックAPI を利用しています。このWebアプリケーションは、JSONリソースを消費するだけの静的サイトとして構築されています。
多くの開発者が、Railsで生成したHTMLフォームやリンクをサーバー間のやりとりに使うではなく、Webアプリケーションを単なるAPIクライアントにとどめて、JSON APIを利用するHTMLとJavaScriptの提供に徹するようになってきました。
本ガイドでは、JSONリソースをAPIクライアントに提供するRailsアプリケーションの構築方法を解説します。クライアント側フレームワークについても言及します。

引用元

雑に表現するのであれば、Railsはデータを返す(基本的にはJSON形式)ことに専念してフロント側は他のアプリケーションに任せるという形になります。

つまりRailsをAPIモードで構築するということは、View(HTMLやCSSやJavaScript)を別のアプリケーション(今回はReact)に任せて、データの送受信に集中する、 ということでもあります。

ここら辺は少し難しいので、最初のうちは「そんなものなのか。」くらいでOKだと思います。自分でコードを書いてアプリケーションを構築していく中で理解を深めていくのが良いかと思います。

APIモードでアプリケーションを構築する

では、下記でRailsのアプリケーションを構築していきます。任意の場所で下記のコマンドを実行してください。

ターミナル
$ rails _6.1.4_ new blog_api --api

コマンドの内容は一つずつ解説していきます。

  • rails _6.1.4_ new blog_api_6.1.4_の部分でプロジェクトで使用するRailsのバージョンを指定しています。このバージョンはお手元にインストールされているPCのバージョンを指定してください。またnewの後のblog_apiは任意でプロジェクトの名前を決めることができます。
  • --api:このオプションをつけるだけでapiモードでRailsを構築することができます。

rails _6.1.4_ new blog_api --apiコマンド実行時に僕の環境でgem関係のエラーが出たので、下記に解決策を書いておきました。特にエラーが出ていない人は読み飛ばしてください🙇‍♂️


エラー(1)

エラー内容

ターミナル
An error occurred while installing puma (5.5.0), and Bundler cannot continue.
Make sure that `gem install puma -v '5.5.0' --source 'https://rubygems.org/'` succeeds before bundling.

解決策

下記のコマンドを実行してpumaをインストールすればOK。筆者の手元にpumaが入っていなかったのでインストールしています。

コマンド
$ sudo gem install puma -v '5.5.0' --source 'https://rubygems.org/'

エラー(2)

エラー内容

ターミナル
An error occurred while installing sqlite3 (1.4.2), and Bundler cannot continue.
Make sure that `gem install sqlite3 -v '1.4.2' --source 'https://rubygems.org/'` succeeds before bundling.

解決策

こちらも同様に下記のコマンドを実行してsqlite3をインストールすればOK。筆者の手元にsqlite3が入っていなかったのでインストールしています。

コマンド
$ sudo gem install sqlite3 -v '1.4.2' --source 'https://rubygems.org/'

次に、ローカル環境ではsqlite3を本番環境ではmysqlを使うようにしたいため、下記のようにGemfileを編集してください。

Gemfile
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.7.4'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails', branch: 'main'
gem 'rails', '~> 6.1.4'
- # Use sqlite3 as the database for Active Record
- gem 'sqlite3', '~> 1.4'
# Use Puma as the app server
gem 'puma', '~> 5.0'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
# gem 'jbuilder', '~> 2.7'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use Active Model has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Use Active Storage variant
# gem 'image_processing', '~> 1.2'

# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.4.4', require: false

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

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
+ gem 'sqlite3', '~> 1.4'
end

group :development do
  gem 'listen', '~> 3.3'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
end

group :production do
+ gem 'mysql2', '~> 0.5'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

上記のように書くことで、環境によって使用するDBを使い分けることができます。

では作成したRailsプロジェクトに移動して、bundle installコマンドを実行してください。

ターミナル
# 作成したRailsプロジェクトに移動
$ cd blog_api

$ bundle install --without production
# 略
Using spring 3.0.0
Using sqlite3 1.4.2
Bundle complete! 8 Gemfile dependencies, 52 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.

下記でbundleとgemについて解説していきます。

bundlerとgemって何?

  • gem:ライブラリのこと
  • bundler:gemfileとgemfile.lockを使って、gemを管理をするライブラリです。

bundlerを通じて、依存関係を極力気にしないでgem(ライブラリ)を管理することができます。bundle installコマンドを使うことでgemfileに記述してある内容を読み込んでライブラリを取り込んでくれます。 具体的な手順としては下記のとおりです。

Railsではgemを追加した時や、初めてプロジェクトを作成した時、githubからプロジェクトをcloneしてきた時などにbundle installする必要があります。

デフォルトのポート番号を変更

bundle installが正常に完了したら次にポート番号を変更しておきましょう。詳細な解説は割愛しますが、このポート番号を変更しておかないとReactプロジェクトとポート番号が重複して、エラーが出てしまいます。

まずはエディタでRailsプロジェクト配下のconfig/puma.rbを開いてください。18行目あたりに下記のような記述があると思います。

config/puma.rb
port ENV.fetch("PORT") { 3000 }

下記のように修正してください。

config/puma.rb
- port ENV.fetch("PORT") { 3000 }
+ port ENV.fetch("PORT") { 3010 }

このようにすることでポート番号3010番でサーバーが立ち上がります。

Railsサーバーを立ち上げてみる

では、下記のコマンドを実行してRailsサーバーを立ち上げてください。

ターミナル
$ rails s
=> Booting Puma
=> Rails 6.1.4.1 application starting in development 
=> Run `bin/rails server --help` for more startup options
Puma starting in single mode...
* Puma version: 5.5.0 (ruby 2.7.4-p191) ("Zawgyi")
*  Min threads: 5
*  Max threads: 5
*  Environment: development
*          PID: 43762
* Listening on http://127.0.0.1:3010
* Listening on http://[::1]:3010
Use Ctrl-C to stop

正常にコマンドが実行されたら http://localhost:3010/ にアクセスしてみてください。下記のような画面が出てきたら成功です!!!

ちなみに、サーバーを停止するにはrails sを実行したターミナルで「Controlキー」を押しながら「C」を押すと停止できます。

DBの作成

下記のコマンドを実行してDBを作成します。

ターミナル
rails db:create

プロダクション環境の設定

次に本番環境ではmysqlを使うため、その設定を書いていきます。config/database.ymlのproductionを下記のように編集してください。

config/database.yml
# 下記のように編集してください。
production:
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  host: <%= ENV['DB_HOST'] %>
  socket: /var/lib/mysql/mysql.sock
  database: blog_api_production
  username: <%= ENV['DB_USERNAME'] %>
  password: <%= ENV['DB_PASSWORD'] %>

それぞれの環境変数はECSのタスク定義ファイル作成時に設定していきます。

CORS(Cross-Origin Resource Sharing)を設定

デフォルトでは、React等の別のオリジンからRailsAPIにアクセス(GET, POST, PUT, DELETEなど)することは制限されています。 なので、フロント側(React)のアプリケーションからのアクセスすることを可能にする設定を書いていかなければいけません。

CORSの設定が簡単にできるgem(ライブラリ)が提供されているので、それを使っていきましょう。

最初にGemfileを編集していきます。26行目あたりにrack-corsという記述がコメントアウトされていると思うので、コメントを外してください。コメントが見つからなかった場合は、ご自身で書き加えてもOKです!

- # gem 'rack-cors'
+ gem 'rack-cors'

次にRailsプロジェクト直下(blog_api)のターミナルでbundle installコマンドを実行してgemを反映させてください。

ターミナル
$ bundle install

実行途中にpasswordが要求されることもあるので、その場合はPCのパスワードを入力してエンターキーを押してください。

次にconfig/initializers/cors.rb配下に設定を書いていきます。下記のように記述してください。

config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins 'http://localhost:3000'

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

http://localhost:3000(Reactプロジェクトで使用予定)からの通信を許可しています。また、この設定を反映させるためにサーバーの再起動が必要なため、rails sを実行したターミナルで「Controlキー」を押しながら「C」を押してサーバーを停止させて、rails sコマンドを実行してサーバーを起動させておいてください。

今回は以上です!お疲れ様でした!