- バックエンド
- PdM
- 急成長中の福利厚生SaaS
- Other occupations (24)
- Development
- Business
- Other
Railsで外部APIを利用する機能のデバッグ方法
Photo by Halogen Condense on Unsplash
ウォンテッドリーでバックエンドエンジニアをしている冨永(@kou_tominaga)です。外部サービスとの通信を伴う機能はローカル環境で動作確認が難しく、ユニットテストでもモックが必要で本番同等の動作確認が困難です。そうした場合、ステージング環境へのデプロイが有力な選択肢となりますが、修正のたびにCI/CDの完了を待って確認するのは非効率です。本記事では、そうした課題に対処するため、ステージング環境を活用して外部サービスとの通信処理を効率的にデバッグする実践的な方法を紹介します。
目次
はじめに
サーバーでrails consoleを実行する
サーバーのコードを直接修正する
通信ログを出力してレスポンスを確認する
まとめ
はじめに
Webアプリケーション開発では、決済、認証、通知、データ連携などの機能は外部サービスのAPIを利用して実現する場合があります。これらはアプリケーションの付加価値を高める一方で、「通信相手が外部にある」という性質によりテストやデバッグが難しくなります。特に問題となるのは、「ローカル環境では実際の通信を再現できない場合」です。外部APIの認証情報がセキュリティ上ローカル環境に置けなかったり、VPN経由でしかアクセスできない内部ネットワークに依存していたりすることが多いため、特定の環境のみでしか挙動を確認できません。
結果として、単純なバグ修正でも「修正 → CI実行 → デプロイ → 動作確認」のサイクルを踏む必要があり、開発効率を大きく下げる要因になります。この記事では、こうした「ローカル環境では再現できない外部通信を伴う処理」を効率的にデバッグするために、ステージング環境を活用して検証するための実践的な方法を紹介します。
サーバーでrails consoleを実行する
最も手軽な方法は、ステージング環境に接続してrails console(rails c)
から直接メソッドを呼び出す方法です。確認したい処理を実行してレスポンスを確認します。
# sshなどでサーバーへログイン
$ ssh dev-server
# rails cを実行
$ rails c
# クラスを呼び出しレスポンスを確認する
result = ExternalApi::Client.new(user_id: 1).fetch_data
puts result
API仕様書だけでは把握できない挙動やパラメータの微妙な差異も、実際に呼び出して確認することで開発の手戻りを防げます。また、取得したレスポンスを元にモックデータを更新することで、テストの信頼性向上にもつながります。
注意: サーバーの DB が他の開発者と共有されている場合、rails c --sandbox
の利用は避けましょう。sandbox モードはセッション中にトランザクションが貼られたままになります。この状態でDBの更新を行うと、対象行に排他ロックがかかり、他の開発者やジョブが同じ行を更新しようとした際に、待機が発生しタイムアウトする可能性があります。
サーバーのコードを直接修正する
ブラウザ操作やUIイベントをトリガーとして実行される処理など、コンソールから直接呼び出せないケースでは、サーバー上のコードを直接修正して挙動を確認する方法が有効です。
# sshなどでサーバーへログイン
$ ssh dev-server
# サーバーのファイルを直接編集
$ vim app/services/external_api/client.rb
# 修正を反映
$ bin/rails restart
この方法の利点は、通信先・ネットワーク設定・環境変数などが実際のユースケースに近い状態で動作を確認できる点です。また、デプロイを待たずに変更を反映できるため、開発サイクルを短縮できます。
注意: 他の開発者と共有しているステージング環境であれば、影響を最小限に抑える工夫(他の処理に影響が無い修正をする、検証後に修正を元に戻す等)を徹底しましょう。
通信ログを出力してレスポンスを確認する
ブラウザの操作をトリガーとする処理で、外部サービスとの通信部分に不具合がある場合、実際のレスポンスを確認したいことがあります。その場合、サーバーのコードを修正してログ出力を仕込む方法が有効です。ログの出力方法には、Railsのロガーを利用する、ファイルへ書き出す、あるいはDBに保存するなど、いくつかの手段があります。
def fetch_data
response = HTTP.get(endpoint, headers: headers)
# ログへの出力
Rails.logger.info("[ExternalAPI] Response: #{response.body}")
# ファイルへの出力
File.open(Rails.root.join("log/external_api.log"), "a") do |f|
f.puts "[#{Time.current}] Response: #{response.body}"
end
# DBへの保存
AdHokLog.create(content: response.body)
response
end
まとめ
外部サービスとの通信を伴う機能のデバッグでは、環境依存やアクセス制約によりローカル環境での再現が難しいことがあります。そうした場合でも、以下の3つのアプローチを使い分けることで、デプロイ待ちの無駄を減らし、開発効率を高めることができます。
これらを状況に応じて組み合わせることで、外部APIを伴う機能の開発をよりスムーズに進めましょう。