🐑

「Rails API とは?普通の Rails と何が違うの?」と思った人がまず読む記事

2023/09/14に公開

この記事は?

Ruby on Rails におけるAPIモードがどのようなものであるのかについて、Webエンジニア初学者向けの解説した記事です。

お断り

この記事は、筆者による史実の主観的な解釈を多いに含みます。

怒る人は怒る表現があるかもしれませんが、初学者にとってのわかりやすさを重視した結果ですので、その場合はそっと優しく教えてくださると幸いです。

結論

早速、結論です。

Rails におけるAPIモードとは、「React.js や Vue.js のような他フロントエンド技術との疎結合な連携を目的として、MVCアーキテクチャーのフロントエンド領域に相当する V(View) を捨てて、 JSON API としてのみ振る舞うバックエンド領域特化のアプリとして開発するモード」です。

はい、何のこっちゃ分からないと思いますので、順を追って説明をしていきます。

そもそも Rails って何がすごいの?

Rails APIモードを理解するためには、まず通常のRailsについて理解を深めるところから始めたいと思います。

そもそも Rails は、2004年にDHH氏によって生み出された、Ruby 言語をベースにしたWebアプリ開発フレームワークです。初期バージョンがリリースされてから20年弱が経過していますが、今でもなお多くの(特に日本の)IT企業で採用されています。

Webアプリ開発フレームワークのひとつとして見た時の Rails の魅力はいくつかあげられると思いますが、そのうちのひとつとして「フロントエンドとバックエンドを両方担えるフルスタックなWebアプリ開発フレームワークであること」が挙げられると思います。

フロントエンドは、アプリケーションのうちユーザーが直接触れる部分の領域を指す言葉です。Webアプリにおいては、HTML/CSS/Javascriptによって記述されたソースコードがブラウザによって実行されることによって、フロントエンド部分が実現されます。

対してバックエンドは、アプリケーションのうちユーザーが直接触れない部分を指す言葉です。例えば、フロントエンド側から受け取ったリクエストに応じてデータベースからデータを取得し、フロントエンド側にレスポンスとして返すといった役割を担います。

Rails はこれらフロントエンド・バックエンドの役割をひとつのフレームワークの中で完結させることができ、高い開発効率を出せるとして支持を集めました。

このように Rails がフルスタックなWebアプリ開発フレームワークとして成立できているのは、RailsがMVCアーキテクチャーという設計思想を採用していることが大きな理由のひとつです。

MVCアーキテクチャーとは?

MVCアーキテクチャーとは、Model-View-Controllerの3つの要素でアプリケーションの根幹を設計するという設計思想です。

  • Model: データベースとのやりとりを管理する要素
  • View: HTML/CSS/JavaScriptを生成する要素
  • Controller: Model と View の間の仲介役に位置し、両者をハンドリングする要素

以下の図は、「ユーザ一覧ページを取得する」過程を例にして、MVCアーキテクチャーの仕組みを示したものです。

① /users にリクエストする

開発環境であればhttp://localhost:3000/users、本番環境であればhttps://www.example.com/usersなどに対して、クライアント(ブラウザ)からリクエストを送信します。

② UsersController#indexを呼び出す

クライアントからのリクエストは、まずルーティング(config/route.rb)に送達し、ルーティングに定義されたコントローラー(UsersController)のアクション(indexアクション)を呼び出します。

③ Userモデルを呼び出す

users レコードをDBから取得するために、まず UsersController#index から Userモデルを呼び出します。

④ usersレコードを取得するクエリをDBに発行する

そしてUserモデルからDBに対して、users レコードを取得するSQLクエリを発行します。

⑤ usersレコードをUserモデルに渡す

SQLクエリを受け取ったDB(画像ではMySQLとしています)は、クエリにしたがって users レコードを取り出し、Userモデルに結果を返します。

⑥ usersレコードをコントローラーに渡す

DBから users レコードを受け取った User モデルは、その内容をそのまま UsersController#index に渡します。

⑦ users レコードをビューに渡す

モデルから users レコードを受け取ったアクションは、その内容を、自身のアクションに対応するビューファイル /users/index.html.erb に渡します。

⑧ usereレコードの基づいて生成された HTML/CSS/Javascript をレスポンスとして返す

ビューはアクションから受け取った users レコードの基づいて HTML/CSS/Javascript を生成し、その結果をクライアント(ブラウザ)に対してレスポンスします。

このような流れで、クライアントはページを閲覧することができます。

フロントエンド技術の進歩

さて、Railsはフルスタックにアプリ開発を行えるフレームワークとして圧倒的な支持を集めてきましたが、徐々にその人気にも陰りが出てしまいます。その理由のひとつが、近年のフロントエンド技術の目覚ましい進歩に追従しきれえなくなってきていること、が挙げられます。

かつてjQueryという Javascript ライブラリの全盛期であった2000年代後半〜2010年前半頃であれば、 Rails の中に jQuery を取り入れるだけで、十分モダンと言えるフロントエンドが実現できていました。

しかし、フロントエンド技術の進歩により、SPA(Single Page Application) という設計方針に注目が集まってきたあたりから、 jQuery の人気が低迷していきます。

SPAの詳細についてはここでは踏み込みませんが、当記事では、

  1. バックエンドよりもフロントエンドの側に重きをおくような設計にすることでよりユーザー体験に優れたアプリケーションを開発していこう、という潮流が強まってきたこと
  2. SPAとjQueryは相性が非常に悪く徐々に嫌煙されるようになってきたこと

という2点の認識が広がっていったという点だけ押さえてもらえたらと思います。

その後2013年になると Facebook からReact.jsがリリースされ、これが前述の SPA を効率良く開発できるライブラリとして広く普及していきました。さらには SPA の弱点を補うような技術として SSR(Server Side Rendering)やSSG(Statice Site Generator)が生まれ、これらを簡単に制御できる React.js フレームワークとして Next.js がVercel社からリリースされました。

また、React.jsとは少し異なる設計思想の Javascript ライブラリとしてVue.jsが登場し、これのフレームワークにあたるNuxt.jsも広く普及しています。現状、「ライブラリとしては React.js と Vue.js が、フレームワークとしては Next.js と Nuxt.js がフロントエンド技術のデファクトスタンダードである」といって差し支えはないでしょう。

このように、近年のフロントエンド技術はとてつもないスピードで進歩し、より優れたユーザー体験を実現できるようになっていきました。その一方で、 React.js や Vue.js のようなモダンなフロントエンド技術は、「フロントエンドに特化したアプリケーションを構築する技術であり、バックエンドは別に用意する」ことを前提としています(特にReact.js系統)。

この前提が、フロントエンドもバックエンドも両方フルスタック的に開発しようとする Rails と食い合わせが悪かったのです。Rails でアプリを構築している以上、jQueryのような一昔前の技術でしかフロントエンドを実装することができず、最先端のフロントエンド技術でしか実現できないようなユーザー体験を提供できない、となってしまったのです。

こういったフロントエンド側の変化をうけ、結果的に Rails は「バックエンドはイケているけれど、フロントエンドはイケてないWeb開発フレームワーク」という見方をする人が増えていってしまいました。

APIモードの登場

上記のようなフロントエンドの弱点を克服するために Rails もさまざまな進化を遂げていきました。それの一環として、Rails5 から登場したのがAPIモードという新しい開発モードです。

APIモードは一言で言えば「Rails でフロントエンドをカバーするのは諦めて、バックエンドだけに特化させる」という開発モードです。

餅は餅屋。ある意味、潔いですね。

APIモードを利用することで、フロントエンドは React.js や Vue.js のようなモダンな技術を採用したアプリを実装し、バックエンドは Rails API でアプリを実装する、といった分かりやすい役割分担を実現できます(=フロントエンドとバックエンドを疎結合にできる)。

APIモードを採用した場合の Rails の挙動をもう少し深掘りします。

以下に、RailsAPIと別のフロントエンド技術を組み合わせた構成での「ユーザー一覧ページ」を閲覧する流れを表した図を示します。

① フロントエンドアプリの /users にアクセスする

クラウアント(ブラウザ)は、まずフロントエンドアプリに対して、「ユーザ一覧ページにアクセスしたいです」というリクエストを送ります。

② Rails の /users にリクエストする

クライアントからのリクエストを受け取ったフロントエンドアプリは、該当ページを描画する前に、さらに Rails に対して「ページに描画に必要になる users レコードをください」というリクエストします。

③〜⑦

ここの流れについては、「1. 通常のRailsアプリ」と同様です。

⑧ users レコードをJSON形式に変換してフロントエンドアプリに渡す

「1. 通常のRailsアプリ」では画面描画に使用する HTML/CSS/Javascript を返していましたが、今回はRailsがAPIモードであるので、JSON形式のデータのみをフロントエンドアプリに返します。

JSONというのは、Javascriptで取り扱いやすい連想配列型のデータ形式のことです。例えば、id:1 の user を取得するリクエストを送信した場合、レスポンスとしては以下のようなJSONデータが想定されます。

 {
   "id": 1,
   "email": "test@example.com",
   "name": "テスト太郎",
 }

図で見るとわかる通り、APIモードのRailsにおいては、MVCアーキテクチャーのうちの V(View) に該当する部分が丸ごとなくなっています。V(View)は HTML/CSS/Javascript を生成する役割を担う部分ですが、レスポンスする中身が単なるJSONデータで良くなったので、V(View)自体が不要となります。

これが結論部分で述べた、「JSON API に徹する(=リクエストに対してJSONのみをレスポンスする)」の意味です。

⑨ Railsから受け取った JSON形式の users レコードに基づいて画面を描画し、クライアント(ブラウザ)に渡す

こういった流れによって、フロントエンドアプリは晴れて users レコードを取得することができたので、これを使用して画面を描画してクライアント(ブラウザ)に渡します。

改めて結論

結論を再掲します。

Rails におけるAPIモードとは、「React.js や Vue.js のような他フロントエンド技術との疎結合な連携を目的として、MVCアーキテクチャーのフロントエンド領域に相当する V(View) を捨てて、 JSON API としてのみ振る舞うバックエンド領域特化のアプリとして開発するモード」です。

ここまで記事を読んでいただいた読者であれば、この文章の意味が分かるようになっているのではないでしょうか?

さいごに

最後まで記事を読んでいただきありがとうございました!。

もしよろしければ、記事の いいねTwitter(X) でのリアクションやアカウントフォロー(@ddpmntcpbr)をお願いします🙏!

最後に宣伝です。zenn上に、RailsAPI+Next.jsの構成でアプリを開発するチュートリアル本をリリースしています。

https://zenn.dev/ddpmntcpbr/books/rna-hands-on

Rails を採用している企業の多くが、フロントエンドとして React.js や Vue.js のようなモダンな技術の採用を進めています。Rails エンジニアとしてのキャリアを進めていくにあたり、APIモードでの開発経験は今後より強く求められていくでしょう。

書籍では「実務未経験者」を主な対象読者として掲げておりますが、通常のRailsアプリに関する実務経験しか積んでいないというジュニアレベルのエンジニアにとっても学びのある内容となっていると思います。

ご興味のある方は、この機会にぜひ手にとっていただけたらと思います。

参考

フロントエンド技術の歴史については、以下の書籍をおおいに参考にしております。本書でかいつまんで説明した以上に詳細な内容が記載されておりますので、ぜひ一度チェックしてみてください。

https://www.amazon.co.jp/TypeScriptとReact-Next-jsでつくる実践Webアプリケーション開発-手島-拓也/dp/4297129167/ref=tmm_pap_swatch_0?_encoding=UTF8&qid=&sr=

GitHubで編集を提案

Discussion