respond_toとフォーマット別処理を完全解説!HTML・JSON・XML・Turbo Streamの使い方まとめ
生徒
「Railsで同じアクションから、HTMLやJSONを切り替えて返せるって聞いたんですけど、本当ですか?」
先生
「はい、本当ですよ。respond_toという仕組みを使えば、リクエストの形式に応じてHTMLやJSON、XML、Turbo Streamなどを返し分けられます。」
生徒
「それって難しいんですか?何か特別な設定が必要なんでしょうか?」
先生
「特別な準備は要りませんよ。Railsではコントローラにrespond_toブロックを書くだけで、簡単にフォーマットごとに処理を切り替えられます。では実際に見ていきましょう!」
1. respond_toとは?
respond_toは、Railsのコントローラでリクエストの種類(フォーマット)に応じた処理を分けるためのメソッドです。HTML形式でアクセスされた場合と、JSON形式でアクセスされた場合で、返す内容を変えたいときに使います。
同じURLにアクセスしても、ブラウザから来たのか、JavaScriptから来たのか、スマホアプリから来たのかで、求められる形式は変わります。その違いをうまく処理するのがrespond_toです。
2. 基本的な使い方(HTMLとJSON)
例えば、一覧ページを表示するとき、HTMLとJSONの両方に対応させるには、次のように書きます。
def index
@books = Book.all
respond_to do |format|
format.html # index.html.erb を表示
format.json { render json: @books }
end
end
この例では、通常のブラウザからのアクセスならindex.html.erbを表示し、APIなどでJSONが要求されたときは@booksの一覧データをJSON形式で返します。
3. format.htmlとrenderの違い
format.htmlだけを書くと、Railsは対応するテンプレート(index.html.erbなど)を自動で探して表示します。一方、format.html { render :custom } のように書けば、別のテンプレートを表示することもできます。
format.html { render :special_list }
これを使えば、状況に応じてテンプレートの切り替えも可能になります。
4. format.jsonでAPIレスポンスを返す
APIを作るときに重要なのがformat.jsonです。次のように書くと、データベースの内容をJSON形式で返せます。
format.json { render json: @user, status: :ok }
status: :okを指定することで、HTTPステータスコード200を明示できます。失敗時は:unprocessable_entity(422)なども使えます。
5. format.xmlでXMLレスポンスにも対応
Railsではformat.xmlを使うことで、XML形式のレスポンスも返すことができます。XMLは、古いシステムや一部のAPI連携で今でも使われています。
format.xml { render xml: @book }
XML形式が必要な相手に対しても、これで対応可能です。
6. Turbo Streamを使ったリアルタイム更新
Rails 7ではformat.turbo_streamで、Turbo Stream形式に対応できます。ページをリロードせずに部分更新を行う、モダンなWebアプリに便利な仕組みです。
format.turbo_stream
これを使うと、JavaScriptなしでもリアルタイムなUI更新ができるようになります。テンプレートとしてはcreate.turbo_stream.erbなどを用意します。
7. フォーマットを切り替える例まとめ
次のように、1つのアクションで複数の形式に対応できます。
respond_to do |format|
format.html
format.json { render json: @item }
format.xml { render xml: @item }
format.turbo_stream
end
このように書いておけば、相手がHTMLでアクセスすればHTMLを返し、スマホアプリからJSONで来たらJSONを返すなど、柔軟な対応が可能になります。
8. formatの順番と注意点
respond_toの中でformat.xxxを複数書くと、リクエストに合ったものが優先して使われます。もし該当する形式がなければ、「406 Not Acceptable」というエラーになる場合もあるので注意しましょう。
また、respond_toは、必ずアクションの最後に書くようにするのが基本です。中間に別の処理があると、思わぬエラーにつながることもあります。
まとめ
respond_toを理解するとRailsアプリの幅が一気に広がる
この記事では、Railsのコントローラで使われる respond_to を中心に、HTML・JSON・XML・Turbo Streamといった複数フォーマットへの対応方法を詳しく解説してきました。Railsは「同じURLで、相手に応じて返す内容を変えられる」という強力な仕組みを最初から備えており、その中核となるのが respond_to です。
Webアプリケーションでは、ブラウザからのアクセスだけでなく、JavaScriptによる非同期通信、スマホアプリからのAPIリクエスト、外部システムとの連携など、さまざまなリクエスト形式が存在します。respond_toを使えば、これらを1つのアクションでまとめて処理できるため、コードの重複を防ぎ、構造をシンプルに保つことができます。
基本となるのは format.html と format.json です。通常の画面表示ではHTMLを返し、APIとして利用される場合はJSONを返す、という構成はRails開発では非常によく使われます。特にJSONレスポンスでは、HTTPステータスコードを明示的に指定できる点も重要で、成功・失敗を正しくクライアントに伝える設計が可能になります。
また、XML形式への対応や、Rails 7以降で注目されている Turbo Stream も respond_to の中で自然に扱える点は、Railsの大きな魅力です。Turbo Streamを使えば、JavaScriptをほとんど書かずに部分更新やリアルタイムな画面反映を実現でき、モダンなユーザー体験をシンプルなコードで構築できます。
respond_to を使ううえで大切なのは、「誰がこのURLにアクセスするのか」を意識することです。人が見る画面なのか、プログラムが利用するAPIなのか、それともリアルタイム更新用のリクエストなのかによって、返すべき形式は変わります。respond_to は、その違いをコードとして明確に表現できるため、アプリ全体の意図が読み取りやすくなります。
注意点として、respond_to の中に定義したフォーマットに一致しないリクエストが来た場合、406エラーになることがあります。そのため、対応する形式をきちんと整理し、不要なフォーマットは無理に追加しないことも重要です。シンプルさを保ちながら、必要な範囲で柔軟に対応するのが理想的な使い方と言えるでしょう。
まとめとしての確認用サンプルプログラム
def show
@article = Article.find(params[:id])
respond_to do |format|
format.html
format.json { render json: @article, status: :ok }
format.turbo_stream
end
end
このサンプルでは、同じshowアクションでHTML表示、JSONレスポンス、Turbo Streamによる部分更新に対応しています。URLは1つでも、アクセス方法によって振る舞いを変えられるのが respond_to の大きな強みです。実際の開発では、この形をベースに機能を拡張していくケースが多くなります。
生徒
「同じアクションでHTMLもJSONも返せるのは、最初は不思議な感じがしました。」
先生
「Railsではよく使われる考え方ですね。アクセスする相手に合わせて返事を変えているだけなんですよ。」
生徒
「APIと画面表示を別々のコントローラにしなくてもいいのが便利だと思いました。」
先生
「そうですね。respond_toを使うと、構造をシンプルに保ちやすくなります。」
生徒
「Turbo Streamも respond_to の中で使えるのは意外でした。」
先生
「Railsらしい一体感のある設計ですよね。これからはフォーマットを意識してコードを書いてみてください。」