Rails APIについて学習しています。
今回は、Railsアプリケーションを使い、をAPIによる例外処理(エラーハンドリング)を実装していきます。
今回やること
- apiのエラーハンドリング処理を実装する。
- 404, 500のレスポンスを返す処理を実装する。
- apiのエラーをjson形式で返す処理を実装する。
base_controller.rbに追記する
module Api
module V1
class BaseController < ApplicationController
include Api::ExceptionHandler
end
end
end
このコードの解説
-
このコードでは、Ruby on Railsのアプリケーションにおけるコントローラの基底クラス
BaseControllerを定義している。 -
module Apimodule V1の部分で、「Api」という名前空間とその下に「V1」という名前空間を作っている。これによって、このコントローラがAPIのバージョン1に関連するものであることを表現している。 -
class BaseController < ApplicationControllerで、BaseControllerというクラスを定義していて、ApplicationControllerを継承している。ApplicationControllerは全てのコントローラが共通で持つ処理を書く場所なので、全てのコントローラはApplicationControllerを継承することになる。 -
include Api::ExceptionHandler。これは、Api::ExceptionHandlerモジュールをこのBaseControllerクラスに取り込む、つまりmix-inしているという事。Api::ExceptionHandlerモジュールはエラーハンドリングのためのメソッドを提供しているから、これによってBaseControllerクラスやそのサブクラスはエラーハンドリングの機能を利用できるようになる。
concernsディレクトリにapiを実装する
module Api::ExceptionHandler
extend ActiveSupport::Concern
included do
rescue_from StandardError, with: :render_500
rescue_from ActiveRecord::RecordNotFound, with: :render_404
end
private
def render_400(exception = nil, messages = nil)
render_error(400, 'Bad Request', exception&.message, *messages)
end
def render_404(exception = nil, messages = nil)
render_error(404, 'Record Not Found', exception&.message, *messages)
end
def render_500(exception = nil, messages = nil)
render_error(500, 'Internal Server Error', exception&.message, *messages)
end
def render_error(code, message, *error_messages)
response = {
message: message,
errors: error_messages.compact
}
render json: response, status: code
end
end
このコードの解説
-
このコードは、Ruby on RailsのアプリケーションでAPIのエラーハンドリングを行なっている部分。
-
concernsディレクトリに定義している。
concernsは、複数のモデから利用される処理を共通化したり、まとまった処理を別に切り出すことで、FatコントローラーやFatモデルを解消するなどの効果がある。 -
module Api::ExceptionHandlerはApi::ExceptionHandlerというモジュールを定義している。このモジュールは、エラーが発生したときの処理をまとめている。 -
extend ActiveSupport::Concernは、ActiveSupport::Concernモジュールを拡張している。これにより、includedというメソッドを使うことができるようになる。 -
included do〜endの中で、rescue_fromメソッドを使ってエラー処理を定義している。例えば、rescue_from ActiveRecord::RecordNotFound, with: :render_404は、ActiveRecord::RecordNotFoundエラーが発生したときに、render_404メソッドを実行する、という指定をしている。 -
render_400、render_404、render_500メソッドは、それぞれHTTPステータスコード400、404、500のエラーが発生したときのレスポンスを作成している。それぞれのメソッドでは、render_errorメソッドを呼び出して、エラーメッセージを含んだJSONレスポンスを作成し、クライアントに返している。 -
最後に、
render_errorメソッドは、エラーレスポンスを生成するためのメソッド。引数として受け取ったHTTPステータスコードとエラーメッセージをもとに、エラーレスポンスをJSON形式で生成している。
可変長引数やオプション引数について
可変長引数やオプション引数を使っています。これについては、こちらの記事が大変参考になりました。